merges closed feature/array branch v2.1

Mon, 30 Dec 2019 09:52:44 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 30 Dec 2019 09:52:44 +0100
changeset 388
871a8ffe6c9d
parent 386
8ebfe95077eb (diff)
parent 387
7e0f19fe23ff (current diff)
child 389
92e482410453
child 471
e9ef2637e101

merges closed feature/array branch

     1.1 --- a/.hgignore	Mon Dec 30 09:52:07 2019 +0100
     1.2 +++ b/.hgignore	Mon Dec 30 09:52:44 2019 +0100
     1.3 @@ -29,3 +29,5 @@
     1.4  ^test/ucxtest
     1.5  /test-suite.log$
     1.6  ^ucx-.*\.tar.gz$
     1.7 +^.idea/
     1.8 +^cmake-build-
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/CHANGELOG	Mon Dec 30 09:52:44 2019 +0100
     2.3 @@ -0,0 +1,38 @@
     2.4 +Version 2.1 - 2019-12-30
     2.5 +------------------------
     2.6 +
     2.7 +* adds string replace functions
     2.8 +* adds set operations for UcxList and UcxMap
     2.9 +* adds sstrcaseprefix() and sstrcasesuffix()
    2.10 +* improves Doxygen documentation in ucx/string.h
    2.11 +* adds UcxArray data type
    2.12 +* adds support for CMake builds, but main build system is still autotools
    2.13 +
    2.14 +Version 2.0 - 2018-12-28
    2.15 +------------------------
    2.16 +
    2.17 +* some uncritical bug fixes
    2.18 +* overflow of sstrnlen now returns SIZE_MAX instead of zero
    2.19 +* adds scstr_t - a const char* variant for sstr_t
    2.20 +* renames utility compare functions
    2.21 +
    2.22 +Version 1.1 - 2018-05-14
    2.23 +------------------------
    2.24 +
    2.25 +* adds missing 32 bit support to integer overflow checks
    2.26 +* adds ucx_buffer_to_sstr() macro
    2.27 +* adds ucx_avl_free_content()
    2.28 +* adds some more compare and distance functions in utils.h
    2.29 +* adds SFMT() and PRIsstr convenience macros
    2.30 +* destructor functions for *_free_content() functions are now optional
    2.31 +
    2.32 +Version 1.0.1 - 2018-01-21
    2.33 +--------------------------
    2.34 +
    2.35 +* some bug fixes
    2.36 +* adds integer overflow checks
    2.37 +
    2.38 +Version 1.0 - 2017-10-28
    2.39 +------------------------
    2.40 +
    2.41 +* first stable version of UCX released
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/CMakeLists.txt	Mon Dec 30 09:52:44 2019 +0100
     3.3 @@ -0,0 +1,40 @@
     3.4 +cmake_minimum_required(VERSION 3.10)
     3.5 +project(ucx VERSION 2.1 DESCRIPTION "UAP Common Extensions")
     3.6 +
     3.7 +# Configuration
     3.8 +set(CMAKE_C_STANDARD 11)
     3.9 +set(CMAKE_C_STANDARD_REQUIRED  99)
    3.10 +
    3.11 +# Library
    3.12 +add_subdirectory(src)
    3.13 +
    3.14 +# Tests
    3.15 +enable_testing()
    3.16 +add_subdirectory(test)
    3.17 +add_test(NAME test COMMAND ucxtest WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test")
    3.18 +
    3.19 +# Web Documentation
    3.20 +add_subdirectory(docs/src)
    3.21 +
    3.22 +# API Documentation
    3.23 +find_package(Doxygen)
    3.24 +option(BUILD_DOCUMENTATION "Create API documentation." ${DOXYGEN_FOUND})
    3.25 +
    3.26 +if(BUILD_DOCUMENTATION)
    3.27 +    if(NOT DOXYGEN_FOUND)
    3.28 +        message(FATAL_ERROR "Doxygen is needed to build the documentation.")
    3.29 +    endif()
    3.30 +
    3.31 +    set(DOXY_INPUT ${CMAKE_SOURCE_DIR}/src)
    3.32 +    set(DOXY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs)
    3.33 +    set(DOXY_PROJECT_LOGO ${CMAKE_SOURCE_DIR}/uaplogo.png)
    3.34 +
    3.35 +    configure_file(${CMAKE_SOURCE_DIR}/cmake_infile.doxygen ${CMAKE_BINARY_DIR}/Doxyfile)
    3.36 +
    3.37 +    add_custom_target(docs-api
    3.38 +            COMMAND ${DOXYGEN_EXECUTABLE}
    3.39 +            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    3.40 +            COMMENT "Generating API documentation with Doxygen")
    3.41 +endif()
    3.42 +
    3.43 +add_custom_target(docs-all DEPENDS docs-html docs-api)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/cmake_infile.doxygen	Mon Dec 30 09:52:44 2019 +0100
     4.3 @@ -0,0 +1,2312 @@
     4.4 +# Doxyfile 1.8.7
     4.5 +
     4.6 +# This file describes the settings to be used by the documentation system
     4.7 +# doxygen (www.doxygen.org) for a project.
     4.8 +#
     4.9 +# All text after a double hash (##) is considered a comment and is placed in
    4.10 +# front of the TAG it is preceding.
    4.11 +#
    4.12 +# All text after a single hash (#) is considered a comment and will be ignored.
    4.13 +# The format is:
    4.14 +# TAG = value [value, ...]
    4.15 +# For lists, items can also be appended using:
    4.16 +# TAG += value [value, ...]
    4.17 +# Values that contain spaces should be placed between quotes (\" \").
    4.18 +
    4.19 +#---------------------------------------------------------------------------
    4.20 +# Project related configuration options
    4.21 +#---------------------------------------------------------------------------
    4.22 +
    4.23 +# This tag specifies the encoding used for all characters in the config file
    4.24 +# that follow. The default is UTF-8 which is also the encoding used for all text
    4.25 +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
    4.26 +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
    4.27 +# for the list of possible encodings.
    4.28 +# The default value is: UTF-8.
    4.29 +
    4.30 +DOXYFILE_ENCODING      = UTF-8
    4.31 +
    4.32 +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
    4.33 +# double-quotes, unless you are using Doxywizard) that should identify the
    4.34 +# project for which the documentation is generated. This name is used in the
    4.35 +# title of most generated pages and in a few other places.
    4.36 +# The default value is: My Project.
    4.37 +
    4.38 +PROJECT_NAME           = "ucx"
    4.39 +
    4.40 +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
    4.41 +# could be handy for archiving the generated documentation or if some version
    4.42 +# control system is used.
    4.43 +
    4.44 +PROJECT_NUMBER         =
    4.45 +
    4.46 +# Using the PROJECT_BRIEF tag one can provide an optional one line description
    4.47 +# for a project that appears at the top of each page and should give viewer a
    4.48 +# quick idea about the purpose of the project. Keep the description short.
    4.49 +
    4.50 +PROJECT_BRIEF          = "UAP Common Extensions"
    4.51 +
    4.52 +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
    4.53 +# the documentation. The maximum height of the logo should not exceed 55 pixels
    4.54 +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
    4.55 +# to the output directory.
    4.56 +
    4.57 +PROJECT_LOGO           = @DOXY_PROJECT_LOGO@
    4.58 +
    4.59 +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
    4.60 +# into which the generated documentation will be written. If a relative path is
    4.61 +# entered, it will be relative to the location where doxygen was started. If
    4.62 +# left blank the current directory will be used.
    4.63 +
    4.64 +OUTPUT_DIRECTORY       = @DOXY_OUTPUT_DIRECTORY@
    4.65 +
    4.66 +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
    4.67 +# directories (in 2 levels) under the output directory of each output format and
    4.68 +# will distribute the generated files over these directories. Enabling this
    4.69 +# option can be useful when feeding doxygen a huge amount of source files, where
    4.70 +# putting all generated files in the same directory would otherwise causes
    4.71 +# performance problems for the file system.
    4.72 +# The default value is: NO.
    4.73 +
    4.74 +CREATE_SUBDIRS         = NO
    4.75 +
    4.76 +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
    4.77 +# characters to appear in the names of generated files. If set to NO, non-ASCII
    4.78 +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
    4.79 +# U+3044.
    4.80 +# The default value is: NO.
    4.81 +
    4.82 +ALLOW_UNICODE_NAMES    = NO
    4.83 +
    4.84 +# The OUTPUT_LANGUAGE tag is used to specify the language in which all
    4.85 +# documentation generated by doxygen is written. Doxygen will use this
    4.86 +# information to generate all constant output in the proper language.
    4.87 +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
    4.88 +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
    4.89 +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
    4.90 +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
    4.91 +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
    4.92 +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
    4.93 +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
    4.94 +# Ukrainian and Vietnamese.
    4.95 +# The default value is: English.
    4.96 +
    4.97 +OUTPUT_LANGUAGE        = English
    4.98 +
    4.99 +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
   4.100 +# descriptions after the members that are listed in the file and class
   4.101 +# documentation (similar to Javadoc). Set to NO to disable this.
   4.102 +# The default value is: YES.
   4.103 +
   4.104 +BRIEF_MEMBER_DESC      = YES
   4.105 +
   4.106 +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
   4.107 +# description of a member or function before the detailed description
   4.108 +#
   4.109 +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
   4.110 +# brief descriptions will be completely suppressed.
   4.111 +# The default value is: YES.
   4.112 +
   4.113 +REPEAT_BRIEF           = YES
   4.114 +
   4.115 +# This tag implements a quasi-intelligent brief description abbreviator that is
   4.116 +# used to form the text in various listings. Each string in this list, if found
   4.117 +# as the leading text of the brief description, will be stripped from the text
   4.118 +# and the result, after processing the whole list, is used as the annotated
   4.119 +# text. Otherwise, the brief description is used as-is. If left blank, the
   4.120 +# following values are used ($name is automatically replaced with the name of
   4.121 +# the entity):The $name class, The $name widget, The $name file, is, provides,
   4.122 +# specifies, contains, represents, a, an and the.
   4.123 +
   4.124 +ABBREVIATE_BRIEF       =
   4.125 +
   4.126 +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
   4.127 +# doxygen will generate a detailed section even if there is only a brief
   4.128 +# description.
   4.129 +# The default value is: NO.
   4.130 +
   4.131 +ALWAYS_DETAILED_SEC    = NO
   4.132 +
   4.133 +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
   4.134 +# inherited members of a class in the documentation of that class as if those
   4.135 +# members were ordinary class members. Constructors, destructors and assignment
   4.136 +# operators of the base classes will not be shown.
   4.137 +# The default value is: NO.
   4.138 +
   4.139 +INLINE_INHERITED_MEMB  = NO
   4.140 +
   4.141 +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
   4.142 +# before files name in the file list and in the header files. If set to NO the
   4.143 +# shortest path that makes the file name unique will be used
   4.144 +# The default value is: YES.
   4.145 +
   4.146 +FULL_PATH_NAMES        = YES
   4.147 +
   4.148 +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
   4.149 +# Stripping is only done if one of the specified strings matches the left-hand
   4.150 +# part of the path. The tag can be used to show relative paths in the file list.
   4.151 +# If left blank the directory from which doxygen is run is used as the path to
   4.152 +# strip.
   4.153 +#
   4.154 +# Note that you can specify absolute paths here, but also relative paths, which
   4.155 +# will be relative from the directory where doxygen is started.
   4.156 +# This tag requires that the tag FULL_PATH_NAMES is set to YES.
   4.157 +
   4.158 +STRIP_FROM_PATH        =
   4.159 +
   4.160 +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
   4.161 +# path mentioned in the documentation of a class, which tells the reader which
   4.162 +# header file to include in order to use a class. If left blank only the name of
   4.163 +# the header file containing the class definition is used. Otherwise one should
   4.164 +# specify the list of include paths that are normally passed to the compiler
   4.165 +# using the -I flag.
   4.166 +
   4.167 +STRIP_FROM_INC_PATH    =
   4.168 +
   4.169 +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
   4.170 +# less readable) file names. This can be useful is your file systems doesn't
   4.171 +# support long names like on DOS, Mac, or CD-ROM.
   4.172 +# The default value is: NO.
   4.173 +
   4.174 +SHORT_NAMES            = NO
   4.175 +
   4.176 +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
   4.177 +# first line (until the first dot) of a Javadoc-style comment as the brief
   4.178 +# description. If set to NO, the Javadoc-style will behave just like regular Qt-
   4.179 +# style comments (thus requiring an explicit @brief command for a brief
   4.180 +# description.)
   4.181 +# The default value is: NO.
   4.182 +
   4.183 +JAVADOC_AUTOBRIEF      = YES
   4.184 +
   4.185 +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
   4.186 +# line (until the first dot) of a Qt-style comment as the brief description. If
   4.187 +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
   4.188 +# requiring an explicit \brief command for a brief description.)
   4.189 +# The default value is: NO.
   4.190 +
   4.191 +QT_AUTOBRIEF           = NO
   4.192 +
   4.193 +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
   4.194 +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
   4.195 +# a brief description. This used to be the default behavior. The new default is
   4.196 +# to treat a multi-line C++ comment block as a detailed description. Set this
   4.197 +# tag to YES if you prefer the old behavior instead.
   4.198 +#
   4.199 +# Note that setting this tag to YES also means that rational rose comments are
   4.200 +# not recognized any more.
   4.201 +# The default value is: NO.
   4.202 +
   4.203 +MULTILINE_CPP_IS_BRIEF = NO
   4.204 +
   4.205 +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
   4.206 +# documentation from any documented member that it re-implements.
   4.207 +# The default value is: YES.
   4.208 +
   4.209 +INHERIT_DOCS           = YES
   4.210 +
   4.211 +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
   4.212 +# new page for each member. If set to NO, the documentation of a member will be
   4.213 +# part of the file/class/namespace that contains it.
   4.214 +# The default value is: NO.
   4.215 +
   4.216 +SEPARATE_MEMBER_PAGES  = NO
   4.217 +
   4.218 +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
   4.219 +# uses this value to replace tabs by spaces in code fragments.
   4.220 +# Minimum value: 1, maximum value: 16, default value: 4.
   4.221 +
   4.222 +TAB_SIZE               = 4
   4.223 +
   4.224 +# This tag can be used to specify a number of aliases that act as commands in
   4.225 +# the documentation. An alias has the form:
   4.226 +# name=value
   4.227 +# For example adding
   4.228 +# "sideeffect=@par Side Effects:\n"
   4.229 +# will allow you to put the command \sideeffect (or @sideeffect) in the
   4.230 +# documentation, which will result in a user-defined paragraph with heading
   4.231 +# "Side Effects:". You can put \n's in the value part of an alias to insert
   4.232 +# newlines.
   4.233 +
   4.234 +ALIASES                =
   4.235 +
   4.236 +# This tag can be used to specify a number of word-keyword mappings (TCL only).
   4.237 +# A mapping has the form "name=value". For example adding "class=itcl::class"
   4.238 +# will allow you to use the command class in the itcl::class meaning.
   4.239 +
   4.240 +TCL_SUBST              =
   4.241 +
   4.242 +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
   4.243 +# only. Doxygen will then generate output that is more tailored for C. For
   4.244 +# instance, some of the names that are used will be different. The list of all
   4.245 +# members will be omitted, etc.
   4.246 +# The default value is: NO.
   4.247 +
   4.248 +OPTIMIZE_OUTPUT_FOR_C  = YES
   4.249 +
   4.250 +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
   4.251 +# Python sources only. Doxygen will then generate output that is more tailored
   4.252 +# for that language. For instance, namespaces will be presented as packages,
   4.253 +# qualified scopes will look different, etc.
   4.254 +# The default value is: NO.
   4.255 +
   4.256 +OPTIMIZE_OUTPUT_JAVA   = NO
   4.257 +
   4.258 +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
   4.259 +# sources. Doxygen will then generate output that is tailored for Fortran.
   4.260 +# The default value is: NO.
   4.261 +
   4.262 +OPTIMIZE_FOR_FORTRAN   = NO
   4.263 +
   4.264 +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
   4.265 +# sources. Doxygen will then generate output that is tailored for VHDL.
   4.266 +# The default value is: NO.
   4.267 +
   4.268 +OPTIMIZE_OUTPUT_VHDL   = NO
   4.269 +
   4.270 +# Doxygen selects the parser to use depending on the extension of the files it
   4.271 +# parses. With this tag you can assign which parser to use for a given
   4.272 +# extension. Doxygen has a built-in mapping, but you can override or extend it
   4.273 +# using this tag. The format is ext=language, where ext is a file extension, and
   4.274 +# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
   4.275 +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
   4.276 +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
   4.277 +# Fortran. In the later case the parser tries to guess whether the code is fixed
   4.278 +# or free formatted code, this is the default for Fortran type files), VHDL. For
   4.279 +# instance to make doxygen treat .inc files as Fortran files (default is PHP),
   4.280 +# and .f files as C (default is Fortran), use: inc=Fortran f=C.
   4.281 +#
   4.282 +# Note For files without extension you can use no_extension as a placeholder.
   4.283 +#
   4.284 +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
   4.285 +# the files are not read by doxygen.
   4.286 +
   4.287 +EXTENSION_MAPPING      =
   4.288 +
   4.289 +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
   4.290 +# according to the Markdown format, which allows for more readable
   4.291 +# documentation. See http://daringfireball.net/projects/markdown/ for details.
   4.292 +# The output of markdown processing is further processed by doxygen, so you can
   4.293 +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
   4.294 +# case of backward compatibilities issues.
   4.295 +# The default value is: YES.
   4.296 +
   4.297 +MARKDOWN_SUPPORT       = YES
   4.298 +
   4.299 +# When enabled doxygen tries to link words that correspond to documented
   4.300 +# classes, or namespaces to their corresponding documentation. Such a link can
   4.301 +# be prevented in individual cases by by putting a % sign in front of the word
   4.302 +# or globally by setting AUTOLINK_SUPPORT to NO.
   4.303 +# The default value is: YES.
   4.304 +
   4.305 +AUTOLINK_SUPPORT       = YES
   4.306 +
   4.307 +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
   4.308 +# to include (a tag file for) the STL sources as input, then you should set this
   4.309 +# tag to YES in order to let doxygen match functions declarations and
   4.310 +# definitions whose arguments contain STL classes (e.g. func(std::string);
   4.311 +# versus func(std::string) {}). This also make the inheritance and collaboration
   4.312 +# diagrams that involve STL classes more complete and accurate.
   4.313 +# The default value is: NO.
   4.314 +
   4.315 +BUILTIN_STL_SUPPORT    = NO
   4.316 +
   4.317 +# If you use Microsoft's C++/CLI language, you should set this option to YES to
   4.318 +# enable parsing support.
   4.319 +# The default value is: NO.
   4.320 +
   4.321 +CPP_CLI_SUPPORT        = NO
   4.322 +
   4.323 +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
   4.324 +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
   4.325 +# will parse them like normal C++ but will assume all classes use public instead
   4.326 +# of private inheritance when no explicit protection keyword is present.
   4.327 +# The default value is: NO.
   4.328 +
   4.329 +SIP_SUPPORT            = NO
   4.330 +
   4.331 +# For Microsoft's IDL there are propget and propput attributes to indicate
   4.332 +# getter and setter methods for a property. Setting this option to YES will make
   4.333 +# doxygen to replace the get and set methods by a property in the documentation.
   4.334 +# This will only work if the methods are indeed getting or setting a simple
   4.335 +# type. If this is not the case, or you want to show the methods anyway, you
   4.336 +# should set this option to NO.
   4.337 +# The default value is: YES.
   4.338 +
   4.339 +IDL_PROPERTY_SUPPORT   = YES
   4.340 +
   4.341 +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
   4.342 +# tag is set to YES, then doxygen will reuse the documentation of the first
   4.343 +# member in the group (if any) for the other members of the group. By default
   4.344 +# all members of a group must be documented explicitly.
   4.345 +# The default value is: NO.
   4.346 +
   4.347 +DISTRIBUTE_GROUP_DOC   = NO
   4.348 +
   4.349 +# Set the SUBGROUPING tag to YES to allow class member groups of the same type
   4.350 +# (for instance a group of public functions) to be put as a subgroup of that
   4.351 +# type (e.g. under the Public Functions section). Set it to NO to prevent
   4.352 +# subgrouping. Alternatively, this can be done per class using the
   4.353 +# \nosubgrouping command.
   4.354 +# The default value is: YES.
   4.355 +
   4.356 +SUBGROUPING            = YES
   4.357 +
   4.358 +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
   4.359 +# are shown inside the group in which they are included (e.g. using \ingroup)
   4.360 +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
   4.361 +# and RTF).
   4.362 +#
   4.363 +# Note that this feature does not work in combination with
   4.364 +# SEPARATE_MEMBER_PAGES.
   4.365 +# The default value is: NO.
   4.366 +
   4.367 +INLINE_GROUPED_CLASSES = NO
   4.368 +
   4.369 +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
   4.370 +# with only public data fields or simple typedef fields will be shown inline in
   4.371 +# the documentation of the scope in which they are defined (i.e. file,
   4.372 +# namespace, or group documentation), provided this scope is documented. If set
   4.373 +# to NO, structs, classes, and unions are shown on a separate page (for HTML and
   4.374 +# Man pages) or section (for LaTeX and RTF).
   4.375 +# The default value is: NO.
   4.376 +
   4.377 +INLINE_SIMPLE_STRUCTS  = NO
   4.378 +
   4.379 +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
   4.380 +# enum is documented as struct, union, or enum with the name of the typedef. So
   4.381 +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
   4.382 +# with name TypeT. When disabled the typedef will appear as a member of a file,
   4.383 +# namespace, or class. And the struct will be named TypeS. This can typically be
   4.384 +# useful for C code in case the coding convention dictates that all compound
   4.385 +# types are typedef'ed and only the typedef is referenced, never the tag name.
   4.386 +# The default value is: NO.
   4.387 +
   4.388 +TYPEDEF_HIDES_STRUCT   = NO
   4.389 +
   4.390 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
   4.391 +# cache is used to resolve symbols given their name and scope. Since this can be
   4.392 +# an expensive process and often the same symbol appears multiple times in the
   4.393 +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
   4.394 +# doxygen will become slower. If the cache is too large, memory is wasted. The
   4.395 +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
   4.396 +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
   4.397 +# symbols. At the end of a run doxygen will report the cache usage and suggest
   4.398 +# the optimal cache size from a speed point of view.
   4.399 +# Minimum value: 0, maximum value: 9, default value: 0.
   4.400 +
   4.401 +LOOKUP_CACHE_SIZE      = 0
   4.402 +
   4.403 +#---------------------------------------------------------------------------
   4.404 +# Build related configuration options
   4.405 +#---------------------------------------------------------------------------
   4.406 +
   4.407 +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
   4.408 +# documentation are documented, even if no documentation was available. Private
   4.409 +# class members and static file members will be hidden unless the
   4.410 +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
   4.411 +# Note: This will also disable the warnings about undocumented members that are
   4.412 +# normally produced when WARNINGS is set to YES.
   4.413 +# The default value is: NO.
   4.414 +
   4.415 +EXTRACT_ALL            = NO
   4.416 +
   4.417 +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
   4.418 +# be included in the documentation.
   4.419 +# The default value is: NO.
   4.420 +
   4.421 +EXTRACT_PRIVATE        = NO
   4.422 +
   4.423 +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
   4.424 +# scope will be included in the documentation.
   4.425 +# The default value is: NO.
   4.426 +
   4.427 +EXTRACT_PACKAGE        = NO
   4.428 +
   4.429 +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
   4.430 +# included in the documentation.
   4.431 +# The default value is: NO.
   4.432 +
   4.433 +EXTRACT_STATIC         = NO
   4.434 +
   4.435 +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
   4.436 +# locally in source files will be included in the documentation. If set to NO
   4.437 +# only classes defined in header files are included. Does not have any effect
   4.438 +# for Java sources.
   4.439 +# The default value is: YES.
   4.440 +
   4.441 +EXTRACT_LOCAL_CLASSES  = YES
   4.442 +
   4.443 +# This flag is only useful for Objective-C code. When set to YES local methods,
   4.444 +# which are defined in the implementation section but not in the interface are
   4.445 +# included in the documentation. If set to NO only methods in the interface are
   4.446 +# included.
   4.447 +# The default value is: NO.
   4.448 +
   4.449 +EXTRACT_LOCAL_METHODS  = NO
   4.450 +
   4.451 +# If this flag is set to YES, the members of anonymous namespaces will be
   4.452 +# extracted and appear in the documentation as a namespace called
   4.453 +# 'anonymous_namespace{file}', where file will be replaced with the base name of
   4.454 +# the file that contains the anonymous namespace. By default anonymous namespace
   4.455 +# are hidden.
   4.456 +# The default value is: NO.
   4.457 +
   4.458 +EXTRACT_ANON_NSPACES   = NO
   4.459 +
   4.460 +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
   4.461 +# undocumented members inside documented classes or files. If set to NO these
   4.462 +# members will be included in the various overviews, but no documentation
   4.463 +# section is generated. This option has no effect if EXTRACT_ALL is enabled.
   4.464 +# The default value is: NO.
   4.465 +
   4.466 +HIDE_UNDOC_MEMBERS     = NO
   4.467 +
   4.468 +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
   4.469 +# undocumented classes that are normally visible in the class hierarchy. If set
   4.470 +# to NO these classes will be included in the various overviews. This option has
   4.471 +# no effect if EXTRACT_ALL is enabled.
   4.472 +# The default value is: NO.
   4.473 +
   4.474 +HIDE_UNDOC_CLASSES     = NO
   4.475 +
   4.476 +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
   4.477 +# (class|struct|union) declarations. If set to NO these declarations will be
   4.478 +# included in the documentation.
   4.479 +# The default value is: NO.
   4.480 +
   4.481 +HIDE_FRIEND_COMPOUNDS  = NO
   4.482 +
   4.483 +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
   4.484 +# documentation blocks found inside the body of a function. If set to NO these
   4.485 +# blocks will be appended to the function's detailed documentation block.
   4.486 +# The default value is: NO.
   4.487 +
   4.488 +HIDE_IN_BODY_DOCS      = NO
   4.489 +
   4.490 +# The INTERNAL_DOCS tag determines if documentation that is typed after a
   4.491 +# \internal command is included. If the tag is set to NO then the documentation
   4.492 +# will be excluded. Set it to YES to include the internal documentation.
   4.493 +# The default value is: NO.
   4.494 +
   4.495 +INTERNAL_DOCS          = NO
   4.496 +
   4.497 +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
   4.498 +# names in lower-case letters. If set to YES upper-case letters are also
   4.499 +# allowed. This is useful if you have classes or files whose names only differ
   4.500 +# in case and if your file system supports case sensitive file names. Windows
   4.501 +# and Mac users are advised to set this option to NO.
   4.502 +# The default value is: system dependent.
   4.503 +
   4.504 +CASE_SENSE_NAMES       = YES
   4.505 +
   4.506 +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
   4.507 +# their full class and namespace scopes in the documentation. If set to YES the
   4.508 +# scope will be hidden.
   4.509 +# The default value is: NO.
   4.510 +
   4.511 +HIDE_SCOPE_NAMES       = NO
   4.512 +
   4.513 +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
   4.514 +# the files that are included by a file in the documentation of that file.
   4.515 +# The default value is: YES.
   4.516 +
   4.517 +SHOW_INCLUDE_FILES     = YES
   4.518 +
   4.519 +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
   4.520 +# grouped member an include statement to the documentation, telling the reader
   4.521 +# which file to include in order to use the member.
   4.522 +# The default value is: NO.
   4.523 +
   4.524 +SHOW_GROUPED_MEMB_INC  = NO
   4.525 +
   4.526 +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
   4.527 +# files with double quotes in the documentation rather than with sharp brackets.
   4.528 +# The default value is: NO.
   4.529 +
   4.530 +FORCE_LOCAL_INCLUDES   = NO
   4.531 +
   4.532 +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
   4.533 +# documentation for inline members.
   4.534 +# The default value is: YES.
   4.535 +
   4.536 +INLINE_INFO            = YES
   4.537 +
   4.538 +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
   4.539 +# (detailed) documentation of file and class members alphabetically by member
   4.540 +# name. If set to NO the members will appear in declaration order.
   4.541 +# The default value is: YES.
   4.542 +
   4.543 +SORT_MEMBER_DOCS       = YES
   4.544 +
   4.545 +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
   4.546 +# descriptions of file, namespace and class members alphabetically by member
   4.547 +# name. If set to NO the members will appear in declaration order. Note that
   4.548 +# this will also influence the order of the classes in the class list.
   4.549 +# The default value is: NO.
   4.550 +
   4.551 +SORT_BRIEF_DOCS        = NO
   4.552 +
   4.553 +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
   4.554 +# (brief and detailed) documentation of class members so that constructors and
   4.555 +# destructors are listed first. If set to NO the constructors will appear in the
   4.556 +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
   4.557 +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
   4.558 +# member documentation.
   4.559 +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
   4.560 +# detailed member documentation.
   4.561 +# The default value is: NO.
   4.562 +
   4.563 +SORT_MEMBERS_CTORS_1ST = NO
   4.564 +
   4.565 +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
   4.566 +# of group names into alphabetical order. If set to NO the group names will
   4.567 +# appear in their defined order.
   4.568 +# The default value is: NO.
   4.569 +
   4.570 +SORT_GROUP_NAMES       = NO
   4.571 +
   4.572 +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
   4.573 +# fully-qualified names, including namespaces. If set to NO, the class list will
   4.574 +# be sorted only by class name, not including the namespace part.
   4.575 +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
   4.576 +# Note: This option applies only to the class list, not to the alphabetical
   4.577 +# list.
   4.578 +# The default value is: NO.
   4.579 +
   4.580 +SORT_BY_SCOPE_NAME     = NO
   4.581 +
   4.582 +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
   4.583 +# type resolution of all parameters of a function it will reject a match between
   4.584 +# the prototype and the implementation of a member function even if there is
   4.585 +# only one candidate or it is obvious which candidate to choose by doing a
   4.586 +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
   4.587 +# accept a match between prototype and implementation in such cases.
   4.588 +# The default value is: NO.
   4.589 +
   4.590 +STRICT_PROTO_MATCHING  = NO
   4.591 +
   4.592 +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
   4.593 +# todo list. This list is created by putting \todo commands in the
   4.594 +# documentation.
   4.595 +# The default value is: YES.
   4.596 +
   4.597 +GENERATE_TODOLIST      = YES
   4.598 +
   4.599 +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
   4.600 +# test list. This list is created by putting \test commands in the
   4.601 +# documentation.
   4.602 +# The default value is: YES.
   4.603 +
   4.604 +GENERATE_TESTLIST      = YES
   4.605 +
   4.606 +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
   4.607 +# list. This list is created by putting \bug commands in the documentation.
   4.608 +# The default value is: YES.
   4.609 +
   4.610 +GENERATE_BUGLIST       = YES
   4.611 +
   4.612 +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
   4.613 +# the deprecated list. This list is created by putting \deprecated commands in
   4.614 +# the documentation.
   4.615 +# The default value is: YES.
   4.616 +
   4.617 +GENERATE_DEPRECATEDLIST= YES
   4.618 +
   4.619 +# The ENABLED_SECTIONS tag can be used to enable conditional documentation
   4.620 +# sections, marked by \if <section_label> ... \endif and \cond <section_label>
   4.621 +# ... \endcond blocks.
   4.622 +
   4.623 +ENABLED_SECTIONS       =
   4.624 +
   4.625 +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
   4.626 +# initial value of a variable or macro / define can have for it to appear in the
   4.627 +# documentation. If the initializer consists of more lines than specified here
   4.628 +# it will be hidden. Use a value of 0 to hide initializers completely. The
   4.629 +# appearance of the value of individual variables and macros / defines can be
   4.630 +# controlled using \showinitializer or \hideinitializer command in the
   4.631 +# documentation regardless of this setting.
   4.632 +# Minimum value: 0, maximum value: 10000, default value: 30.
   4.633 +
   4.634 +MAX_INITIALIZER_LINES  = 30
   4.635 +
   4.636 +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
   4.637 +# the bottom of the documentation of classes and structs. If set to YES the list
   4.638 +# will mention the files that were used to generate the documentation.
   4.639 +# The default value is: YES.
   4.640 +
   4.641 +SHOW_USED_FILES        = YES
   4.642 +
   4.643 +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
   4.644 +# will remove the Files entry from the Quick Index and from the Folder Tree View
   4.645 +# (if specified).
   4.646 +# The default value is: YES.
   4.647 +
   4.648 +SHOW_FILES             = YES
   4.649 +
   4.650 +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
   4.651 +# page. This will remove the Namespaces entry from the Quick Index and from the
   4.652 +# Folder Tree View (if specified).
   4.653 +# The default value is: YES.
   4.654 +
   4.655 +SHOW_NAMESPACES        = YES
   4.656 +
   4.657 +# The FILE_VERSION_FILTER tag can be used to specify a program or script that
   4.658 +# doxygen should invoke to get the current version for each file (typically from
   4.659 +# the version control system). Doxygen will invoke the program by executing (via
   4.660 +# popen()) the command command input-file, where command is the value of the
   4.661 +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
   4.662 +# by doxygen. Whatever the program writes to standard output is used as the file
   4.663 +# version. For an example see the documentation.
   4.664 +
   4.665 +FILE_VERSION_FILTER    =
   4.666 +
   4.667 +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
   4.668 +# by doxygen. The layout file controls the global structure of the generated
   4.669 +# output files in an output format independent way. To create the layout file
   4.670 +# that represents doxygen's defaults, run doxygen with the -l option. You can
   4.671 +# optionally specify a file name after the option, if omitted DoxygenLayout.xml
   4.672 +# will be used as the name of the layout file.
   4.673 +#
   4.674 +# Note that if you run doxygen from a directory containing a file called
   4.675 +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
   4.676 +# tag is left empty.
   4.677 +
   4.678 +LAYOUT_FILE            =
   4.679 +
   4.680 +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
   4.681 +# the reference definitions. This must be a list of .bib files. The .bib
   4.682 +# extension is automatically appended if omitted. This requires the bibtex tool
   4.683 +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
   4.684 +# For LaTeX the style of the bibliography can be controlled using
   4.685 +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
   4.686 +# search path. Do not use file names with spaces, bibtex cannot handle them. See
   4.687 +# also \cite for info how to create references.
   4.688 +
   4.689 +CITE_BIB_FILES         =
   4.690 +
   4.691 +#---------------------------------------------------------------------------
   4.692 +# Configuration options related to warning and progress messages
   4.693 +#---------------------------------------------------------------------------
   4.694 +
   4.695 +# The QUIET tag can be used to turn on/off the messages that are generated to
   4.696 +# standard output by doxygen. If QUIET is set to YES this implies that the
   4.697 +# messages are off.
   4.698 +# The default value is: NO.
   4.699 +
   4.700 +QUIET                  = YES
   4.701 +
   4.702 +# The WARNINGS tag can be used to turn on/off the warning messages that are
   4.703 +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
   4.704 +# this implies that the warnings are on.
   4.705 +#
   4.706 +# Tip: Turn warnings on while writing the documentation.
   4.707 +# The default value is: YES.
   4.708 +
   4.709 +WARNINGS               = YES
   4.710 +
   4.711 +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
   4.712 +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
   4.713 +# will automatically be disabled.
   4.714 +# The default value is: YES.
   4.715 +
   4.716 +WARN_IF_UNDOCUMENTED   = YES
   4.717 +
   4.718 +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
   4.719 +# potential errors in the documentation, such as not documenting some parameters
   4.720 +# in a documented function, or documenting parameters that don't exist or using
   4.721 +# markup commands wrongly.
   4.722 +# The default value is: YES.
   4.723 +
   4.724 +WARN_IF_DOC_ERROR      = YES
   4.725 +
   4.726 +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
   4.727 +# are documented, but have no documentation for their parameters or return
   4.728 +# value. If set to NO doxygen will only warn about wrong or incomplete parameter
   4.729 +# documentation, but not about the absence of documentation.
   4.730 +# The default value is: NO.
   4.731 +
   4.732 +WARN_NO_PARAMDOC       = YES
   4.733 +
   4.734 +# The WARN_FORMAT tag determines the format of the warning messages that doxygen
   4.735 +# can produce. The string should contain the $file, $line, and $text tags, which
   4.736 +# will be replaced by the file and line number from which the warning originated
   4.737 +# and the warning text. Optionally the format may contain $version, which will
   4.738 +# be replaced by the version of the file (if it could be obtained via
   4.739 +# FILE_VERSION_FILTER)
   4.740 +# The default value is: $file:$line: $text.
   4.741 +
   4.742 +WARN_FORMAT            = "$file:$line: $text"
   4.743 +
   4.744 +# The WARN_LOGFILE tag can be used to specify a file to which warning and error
   4.745 +# messages should be written. If left blank the output is written to standard
   4.746 +# error (stderr).
   4.747 +
   4.748 +WARN_LOGFILE           =
   4.749 +
   4.750 +#---------------------------------------------------------------------------
   4.751 +# Configuration options related to the input files
   4.752 +#---------------------------------------------------------------------------
   4.753 +
   4.754 +# The INPUT tag is used to specify the files and/or directories that contain
   4.755 +# documented source files. You may enter file names like myfile.cpp or
   4.756 +# directories like /usr/src/myproject. Separate the files or directories with
   4.757 +# spaces.
   4.758 +# Note: If this tag is empty the current directory is searched.
   4.759 +
   4.760 +INPUT                  = @DOXY_INPUT@
   4.761 +
   4.762 +# This tag can be used to specify the character encoding of the source files
   4.763 +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
   4.764 +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
   4.765 +# documentation (see: http://www.gnu.org/software/libiconv) for the list of
   4.766 +# possible encodings.
   4.767 +# The default value is: UTF-8.
   4.768 +
   4.769 +INPUT_ENCODING         = UTF-8
   4.770 +
   4.771 +# If the value of the INPUT tag contains directories, you can use the
   4.772 +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
   4.773 +# *.h) to filter out the source-files in the directories. If left blank the
   4.774 +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
   4.775 +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
   4.776 +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
   4.777 +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
   4.778 +# *.qsf, *.as and *.js.
   4.779 +
   4.780 +FILE_PATTERNS          =
   4.781 +
   4.782 +# The RECURSIVE tag can be used to specify whether or not subdirectories should
   4.783 +# be searched for input files as well.
   4.784 +# The default value is: NO.
   4.785 +
   4.786 +RECURSIVE              = YES
   4.787 +
   4.788 +# The EXCLUDE tag can be used to specify files and/or directories that should be
   4.789 +# excluded from the INPUT source files. This way you can easily exclude a
   4.790 +# subdirectory from a directory tree whose root is specified with the INPUT tag.
   4.791 +#
   4.792 +# Note that relative paths are relative to the directory from which doxygen is
   4.793 +# run.
   4.794 +
   4.795 +EXCLUDE                =
   4.796 +
   4.797 +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
   4.798 +# directories that are symbolic links (a Unix file system feature) are excluded
   4.799 +# from the input.
   4.800 +# The default value is: NO.
   4.801 +
   4.802 +EXCLUDE_SYMLINKS       = NO
   4.803 +
   4.804 +# If the value of the INPUT tag contains directories, you can use the
   4.805 +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
   4.806 +# certain files from those directories.
   4.807 +#
   4.808 +# Note that the wildcards are matched against the file with absolute path, so to
   4.809 +# exclude all test directories for example use the pattern */test/*
   4.810 +
   4.811 +EXCLUDE_PATTERNS       =
   4.812 +
   4.813 +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
   4.814 +# (namespaces, classes, functions, etc.) that should be excluded from the
   4.815 +# output. The symbol name can be a fully qualified name, a word, or if the
   4.816 +# wildcard * is used, a substring. Examples: ANamespace, AClass,
   4.817 +# AClass::ANamespace, ANamespace::*Test
   4.818 +#
   4.819 +# Note that the wildcards are matched against the file with absolute path, so to
   4.820 +# exclude all test directories use the pattern */test/*
   4.821 +
   4.822 +EXCLUDE_SYMBOLS        =
   4.823 +
   4.824 +# The EXAMPLE_PATH tag can be used to specify one or more files or directories
   4.825 +# that contain example code fragments that are included (see the \include
   4.826 +# command).
   4.827 +
   4.828 +EXAMPLE_PATH           =
   4.829 +
   4.830 +# If the value of the EXAMPLE_PATH tag contains directories, you can use the
   4.831 +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
   4.832 +# *.h) to filter out the source-files in the directories. If left blank all
   4.833 +# files are included.
   4.834 +
   4.835 +EXAMPLE_PATTERNS       =
   4.836 +
   4.837 +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
   4.838 +# searched for input files to be used with the \include or \dontinclude commands
   4.839 +# irrespective of the value of the RECURSIVE tag.
   4.840 +# The default value is: NO.
   4.841 +
   4.842 +EXAMPLE_RECURSIVE      = NO
   4.843 +
   4.844 +# The IMAGE_PATH tag can be used to specify one or more files or directories
   4.845 +# that contain images that are to be included in the documentation (see the
   4.846 +# \image command).
   4.847 +
   4.848 +IMAGE_PATH             =
   4.849 +
   4.850 +# The INPUT_FILTER tag can be used to specify a program that doxygen should
   4.851 +# invoke to filter for each input file. Doxygen will invoke the filter program
   4.852 +# by executing (via popen()) the command:
   4.853 +#
   4.854 +# <filter> <input-file>
   4.855 +#
   4.856 +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
   4.857 +# name of an input file. Doxygen will then use the output that the filter
   4.858 +# program writes to standard output. If FILTER_PATTERNS is specified, this tag
   4.859 +# will be ignored.
   4.860 +#
   4.861 +# Note that the filter must not add or remove lines; it is applied before the
   4.862 +# code is scanned, but not when the output code is generated. If lines are added
   4.863 +# or removed, the anchors will not be placed correctly.
   4.864 +
   4.865 +INPUT_FILTER           =
   4.866 +
   4.867 +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
   4.868 +# basis. Doxygen will compare the file name with each pattern and apply the
   4.869 +# filter if there is a match. The filters are a list of the form: pattern=filter
   4.870 +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
   4.871 +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
   4.872 +# patterns match the file name, INPUT_FILTER is applied.
   4.873 +
   4.874 +FILTER_PATTERNS        =
   4.875 +
   4.876 +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
   4.877 +# INPUT_FILTER ) will also be used to filter the input files that are used for
   4.878 +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
   4.879 +# The default value is: NO.
   4.880 +
   4.881 +FILTER_SOURCE_FILES    = NO
   4.882 +
   4.883 +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
   4.884 +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
   4.885 +# it is also possible to disable source filtering for a specific pattern using
   4.886 +# *.ext= (so without naming a filter).
   4.887 +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
   4.888 +
   4.889 +FILTER_SOURCE_PATTERNS =
   4.890 +
   4.891 +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
   4.892 +# is part of the input, its contents will be placed on the main page
   4.893 +# (index.html). This can be useful if you have a project on for instance GitHub
   4.894 +# and want to reuse the introduction page also for the doxygen output.
   4.895 +
   4.896 +USE_MDFILE_AS_MAINPAGE =
   4.897 +
   4.898 +#---------------------------------------------------------------------------
   4.899 +# Configuration options related to source browsing
   4.900 +#---------------------------------------------------------------------------
   4.901 +
   4.902 +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
   4.903 +# generated. Documented entities will be cross-referenced with these sources.
   4.904 +#
   4.905 +# Note: To get rid of all source code in the generated output, make sure that
   4.906 +# also VERBATIM_HEADERS is set to NO.
   4.907 +# The default value is: NO.
   4.908 +
   4.909 +SOURCE_BROWSER         = NO
   4.910 +
   4.911 +# Setting the INLINE_SOURCES tag to YES will include the body of functions,
   4.912 +# classes and enums directly into the documentation.
   4.913 +# The default value is: NO.
   4.914 +
   4.915 +INLINE_SOURCES         = NO
   4.916 +
   4.917 +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
   4.918 +# special comment blocks from generated source code fragments. Normal C, C++ and
   4.919 +# Fortran comments will always remain visible.
   4.920 +# The default value is: YES.
   4.921 +
   4.922 +STRIP_CODE_COMMENTS    = YES
   4.923 +
   4.924 +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
   4.925 +# function all documented functions referencing it will be listed.
   4.926 +# The default value is: NO.
   4.927 +
   4.928 +REFERENCED_BY_RELATION = NO
   4.929 +
   4.930 +# If the REFERENCES_RELATION tag is set to YES then for each documented function
   4.931 +# all documented entities called/used by that function will be listed.
   4.932 +# The default value is: NO.
   4.933 +
   4.934 +REFERENCES_RELATION    = NO
   4.935 +
   4.936 +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
   4.937 +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
   4.938 +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
   4.939 +# link to the documentation.
   4.940 +# The default value is: YES.
   4.941 +
   4.942 +REFERENCES_LINK_SOURCE = YES
   4.943 +
   4.944 +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
   4.945 +# source code will show a tooltip with additional information such as prototype,
   4.946 +# brief description and links to the definition and documentation. Since this
   4.947 +# will make the HTML file larger and loading of large files a bit slower, you
   4.948 +# can opt to disable this feature.
   4.949 +# The default value is: YES.
   4.950 +# This tag requires that the tag SOURCE_BROWSER is set to YES.
   4.951 +
   4.952 +SOURCE_TOOLTIPS        = YES
   4.953 +
   4.954 +# If the USE_HTAGS tag is set to YES then the references to source code will
   4.955 +# point to the HTML generated by the htags(1) tool instead of doxygen built-in
   4.956 +# source browser. The htags tool is part of GNU's global source tagging system
   4.957 +# (see http://www.gnu.org/software/global/global.html). You will need version
   4.958 +# 4.8.6 or higher.
   4.959 +#
   4.960 +# To use it do the following:
   4.961 +# - Install the latest version of global
   4.962 +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
   4.963 +# - Make sure the INPUT points to the root of the source tree
   4.964 +# - Run doxygen as normal
   4.965 +#
   4.966 +# Doxygen will invoke htags (and that will in turn invoke gtags), so these
   4.967 +# tools must be available from the command line (i.e. in the search path).
   4.968 +#
   4.969 +# The result: instead of the source browser generated by doxygen, the links to
   4.970 +# source code will now point to the output of htags.
   4.971 +# The default value is: NO.
   4.972 +# This tag requires that the tag SOURCE_BROWSER is set to YES.
   4.973 +
   4.974 +USE_HTAGS              = NO
   4.975 +
   4.976 +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
   4.977 +# verbatim copy of the header file for each class for which an include is
   4.978 +# specified. Set to NO to disable this.
   4.979 +# See also: Section \class.
   4.980 +# The default value is: YES.
   4.981 +
   4.982 +VERBATIM_HEADERS       = YES
   4.983 +
   4.984 +#---------------------------------------------------------------------------
   4.985 +# Configuration options related to the alphabetical class index
   4.986 +#---------------------------------------------------------------------------
   4.987 +
   4.988 +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
   4.989 +# compounds will be generated. Enable this if the project contains a lot of
   4.990 +# classes, structs, unions or interfaces.
   4.991 +# The default value is: YES.
   4.992 +
   4.993 +ALPHABETICAL_INDEX     = YES
   4.994 +
   4.995 +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
   4.996 +# which the alphabetical index list will be split.
   4.997 +# Minimum value: 1, maximum value: 20, default value: 5.
   4.998 +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
   4.999 +
  4.1000 +COLS_IN_ALPHA_INDEX    = 5
  4.1001 +
  4.1002 +# In case all classes in a project start with a common prefix, all classes will
  4.1003 +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
  4.1004 +# can be used to specify a prefix (or a list of prefixes) that should be ignored
  4.1005 +# while generating the index headers.
  4.1006 +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
  4.1007 +
  4.1008 +IGNORE_PREFIX          =
  4.1009 +
  4.1010 +#---------------------------------------------------------------------------
  4.1011 +# Configuration options related to the HTML output
  4.1012 +#---------------------------------------------------------------------------
  4.1013 +
  4.1014 +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
  4.1015 +# The default value is: YES.
  4.1016 +
  4.1017 +GENERATE_HTML          = YES
  4.1018 +
  4.1019 +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
  4.1020 +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
  4.1021 +# it.
  4.1022 +# The default directory is: html.
  4.1023 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1024 +
  4.1025 +HTML_OUTPUT            = web/api
  4.1026 +
  4.1027 +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
  4.1028 +# generated HTML page (for example: .htm, .php, .asp).
  4.1029 +# The default value is: .html.
  4.1030 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1031 +
  4.1032 +HTML_FILE_EXTENSION    = .html
  4.1033 +
  4.1034 +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
  4.1035 +# each generated HTML page. If the tag is left blank doxygen will generate a
  4.1036 +# standard header.
  4.1037 +#
  4.1038 +# To get valid HTML the header file that includes any scripts and style sheets
  4.1039 +# that doxygen needs, which is dependent on the configuration options used (e.g.
  4.1040 +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
  4.1041 +# default header using
  4.1042 +# doxygen -w html new_header.html new_footer.html new_stylesheet.css
  4.1043 +# YourConfigFile
  4.1044 +# and then modify the file new_header.html. See also section "Doxygen usage"
  4.1045 +# for information on how to generate the default header that doxygen normally
  4.1046 +# uses.
  4.1047 +# Note: The header is subject to change so you typically have to regenerate the
  4.1048 +# default header when upgrading to a newer version of doxygen. For a description
  4.1049 +# of the possible markers and block names see the documentation.
  4.1050 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1051 +
  4.1052 +HTML_HEADER            =
  4.1053 +
  4.1054 +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
  4.1055 +# generated HTML page. If the tag is left blank doxygen will generate a standard
  4.1056 +# footer. See HTML_HEADER for more information on how to generate a default
  4.1057 +# footer and what special commands can be used inside the footer. See also
  4.1058 +# section "Doxygen usage" for information on how to generate the default footer
  4.1059 +# that doxygen normally uses.
  4.1060 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1061 +
  4.1062 +HTML_FOOTER            =
  4.1063 +
  4.1064 +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
  4.1065 +# sheet that is used by each HTML page. It can be used to fine-tune the look of
  4.1066 +# the HTML output. If left blank doxygen will generate a default style sheet.
  4.1067 +# See also section "Doxygen usage" for information on how to generate the style
  4.1068 +# sheet that doxygen normally uses.
  4.1069 +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
  4.1070 +# it is more robust and this tag (HTML_STYLESHEET) will in the future become
  4.1071 +# obsolete.
  4.1072 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1073 +
  4.1074 +HTML_STYLESHEET        =
  4.1075 +
  4.1076 +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
  4.1077 +# defined cascading style sheet that is included after the standard style sheets
  4.1078 +# created by doxygen. Using this option one can overrule certain style aspects.
  4.1079 +# This is preferred over using HTML_STYLESHEET since it does not replace the
  4.1080 +# standard style sheet and is therefor more robust against future updates.
  4.1081 +# Doxygen will copy the style sheet file to the output directory. For an example
  4.1082 +# see the documentation.
  4.1083 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1084 +
  4.1085 +HTML_EXTRA_STYLESHEET  =
  4.1086 +
  4.1087 +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
  4.1088 +# other source files which should be copied to the HTML output directory. Note
  4.1089 +# that these files will be copied to the base HTML output directory. Use the
  4.1090 +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
  4.1091 +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
  4.1092 +# files will be copied as-is; there are no commands or markers available.
  4.1093 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1094 +
  4.1095 +HTML_EXTRA_FILES       =
  4.1096 +
  4.1097 +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
  4.1098 +# will adjust the colors in the stylesheet and background images according to
  4.1099 +# this color. Hue is specified as an angle on a colorwheel, see
  4.1100 +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
  4.1101 +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
  4.1102 +# purple, and 360 is red again.
  4.1103 +# Minimum value: 0, maximum value: 359, default value: 220.
  4.1104 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1105 +
  4.1106 +HTML_COLORSTYLE_HUE    = 220
  4.1107 +
  4.1108 +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
  4.1109 +# in the HTML output. For a value of 0 the output will use grayscales only. A
  4.1110 +# value of 255 will produce the most vivid colors.
  4.1111 +# Minimum value: 0, maximum value: 255, default value: 100.
  4.1112 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1113 +
  4.1114 +HTML_COLORSTYLE_SAT    = 100
  4.1115 +
  4.1116 +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
  4.1117 +# luminance component of the colors in the HTML output. Values below 100
  4.1118 +# gradually make the output lighter, whereas values above 100 make the output
  4.1119 +# darker. The value divided by 100 is the actual gamma applied, so 80 represents
  4.1120 +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
  4.1121 +# change the gamma.
  4.1122 +# Minimum value: 40, maximum value: 240, default value: 80.
  4.1123 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1124 +
  4.1125 +HTML_COLORSTYLE_GAMMA  = 80
  4.1126 +
  4.1127 +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
  4.1128 +# page will contain the date and time when the page was generated. Setting this
  4.1129 +# to NO can help when comparing the output of multiple runs.
  4.1130 +# The default value is: YES.
  4.1131 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1132 +
  4.1133 +HTML_TIMESTAMP         = YES
  4.1134 +
  4.1135 +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
  4.1136 +# documentation will contain sections that can be hidden and shown after the
  4.1137 +# page has loaded.
  4.1138 +# The default value is: NO.
  4.1139 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1140 +
  4.1141 +HTML_DYNAMIC_SECTIONS  = NO
  4.1142 +
  4.1143 +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
  4.1144 +# shown in the various tree structured indices initially; the user can expand
  4.1145 +# and collapse entries dynamically later on. Doxygen will expand the tree to
  4.1146 +# such a level that at most the specified number of entries are visible (unless
  4.1147 +# a fully collapsed tree already exceeds this amount). So setting the number of
  4.1148 +# entries 1 will produce a full collapsed tree by default. 0 is a special value
  4.1149 +# representing an infinite number of entries and will result in a full expanded
  4.1150 +# tree by default.
  4.1151 +# Minimum value: 0, maximum value: 9999, default value: 100.
  4.1152 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1153 +
  4.1154 +HTML_INDEX_NUM_ENTRIES = 100
  4.1155 +
  4.1156 +# If the GENERATE_DOCSET tag is set to YES, additional index files will be
  4.1157 +# generated that can be used as input for Apple's Xcode 3 integrated development
  4.1158 +# environment (see: http://developer.apple.com/tools/xcode/), introduced with
  4.1159 +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
  4.1160 +# Makefile in the HTML output directory. Running make will produce the docset in
  4.1161 +# that directory and running make install will install the docset in
  4.1162 +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
  4.1163 +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
  4.1164 +# for more information.
  4.1165 +# The default value is: NO.
  4.1166 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1167 +
  4.1168 +GENERATE_DOCSET        = NO
  4.1169 +
  4.1170 +# This tag determines the name of the docset feed. A documentation feed provides
  4.1171 +# an umbrella under which multiple documentation sets from a single provider
  4.1172 +# (such as a company or product suite) can be grouped.
  4.1173 +# The default value is: Doxygen generated docs.
  4.1174 +# This tag requires that the tag GENERATE_DOCSET is set to YES.
  4.1175 +
  4.1176 +DOCSET_FEEDNAME        = "Doxygen generated docs"
  4.1177 +
  4.1178 +# This tag specifies a string that should uniquely identify the documentation
  4.1179 +# set bundle. This should be a reverse domain-name style string, e.g.
  4.1180 +# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
  4.1181 +# The default value is: org.doxygen.Project.
  4.1182 +# This tag requires that the tag GENERATE_DOCSET is set to YES.
  4.1183 +
  4.1184 +DOCSET_BUNDLE_ID       = org.doxygen.Project
  4.1185 +
  4.1186 +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
  4.1187 +# the documentation publisher. This should be a reverse domain-name style
  4.1188 +# string, e.g. com.mycompany.MyDocSet.documentation.
  4.1189 +# The default value is: org.doxygen.Publisher.
  4.1190 +# This tag requires that the tag GENERATE_DOCSET is set to YES.
  4.1191 +
  4.1192 +DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
  4.1193 +
  4.1194 +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
  4.1195 +# The default value is: Publisher.
  4.1196 +# This tag requires that the tag GENERATE_DOCSET is set to YES.
  4.1197 +
  4.1198 +DOCSET_PUBLISHER_NAME  = Publisher
  4.1199 +
  4.1200 +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
  4.1201 +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
  4.1202 +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
  4.1203 +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
  4.1204 +# Windows.
  4.1205 +#
  4.1206 +# The HTML Help Workshop contains a compiler that can convert all HTML output
  4.1207 +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
  4.1208 +# files are now used as the Windows 98 help format, and will replace the old
  4.1209 +# Windows help format (.hlp) on all Windows platforms in the future. Compressed
  4.1210 +# HTML files also contain an index, a table of contents, and you can search for
  4.1211 +# words in the documentation. The HTML workshop also contains a viewer for
  4.1212 +# compressed HTML files.
  4.1213 +# The default value is: NO.
  4.1214 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1215 +
  4.1216 +GENERATE_HTMLHELP      = NO
  4.1217 +
  4.1218 +# The CHM_FILE tag can be used to specify the file name of the resulting .chm
  4.1219 +# file. You can add a path in front of the file if the result should not be
  4.1220 +# written to the html output directory.
  4.1221 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1222 +
  4.1223 +CHM_FILE               =
  4.1224 +
  4.1225 +# The HHC_LOCATION tag can be used to specify the location (absolute path
  4.1226 +# including file name) of the HTML help compiler ( hhc.exe). If non-empty
  4.1227 +# doxygen will try to run the HTML help compiler on the generated index.hhp.
  4.1228 +# The file has to be specified with full path.
  4.1229 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1230 +
  4.1231 +HHC_LOCATION           =
  4.1232 +
  4.1233 +# The GENERATE_CHI flag controls if a separate .chi index file is generated (
  4.1234 +# YES) or that it should be included in the master .chm file ( NO).
  4.1235 +# The default value is: NO.
  4.1236 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1237 +
  4.1238 +GENERATE_CHI           = NO
  4.1239 +
  4.1240 +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
  4.1241 +# and project file content.
  4.1242 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1243 +
  4.1244 +CHM_INDEX_ENCODING     =
  4.1245 +
  4.1246 +# The BINARY_TOC flag controls whether a binary table of contents is generated (
  4.1247 +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
  4.1248 +# enables the Previous and Next buttons.
  4.1249 +# The default value is: NO.
  4.1250 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1251 +
  4.1252 +BINARY_TOC             = NO
  4.1253 +
  4.1254 +# The TOC_EXPAND flag can be set to YES to add extra items for group members to
  4.1255 +# the table of contents of the HTML help documentation and to the tree view.
  4.1256 +# The default value is: NO.
  4.1257 +# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
  4.1258 +
  4.1259 +TOC_EXPAND             = NO
  4.1260 +
  4.1261 +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
  4.1262 +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
  4.1263 +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
  4.1264 +# (.qch) of the generated HTML documentation.
  4.1265 +# The default value is: NO.
  4.1266 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1267 +
  4.1268 +GENERATE_QHP           = NO
  4.1269 +
  4.1270 +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
  4.1271 +# the file name of the resulting .qch file. The path specified is relative to
  4.1272 +# the HTML output folder.
  4.1273 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1274 +
  4.1275 +QCH_FILE               =
  4.1276 +
  4.1277 +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
  4.1278 +# Project output. For more information please see Qt Help Project / Namespace
  4.1279 +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
  4.1280 +# The default value is: org.doxygen.Project.
  4.1281 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1282 +
  4.1283 +QHP_NAMESPACE          = org.doxygen.Project
  4.1284 +
  4.1285 +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
  4.1286 +# Help Project output. For more information please see Qt Help Project / Virtual
  4.1287 +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
  4.1288 +# folders).
  4.1289 +# The default value is: doc.
  4.1290 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1291 +
  4.1292 +QHP_VIRTUAL_FOLDER     = doc
  4.1293 +
  4.1294 +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
  4.1295 +# filter to add. For more information please see Qt Help Project / Custom
  4.1296 +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
  4.1297 +# filters).
  4.1298 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1299 +
  4.1300 +QHP_CUST_FILTER_NAME   =
  4.1301 +
  4.1302 +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
  4.1303 +# custom filter to add. For more information please see Qt Help Project / Custom
  4.1304 +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
  4.1305 +# filters).
  4.1306 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1307 +
  4.1308 +QHP_CUST_FILTER_ATTRS  =
  4.1309 +
  4.1310 +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
  4.1311 +# project's filter section matches. Qt Help Project / Filter Attributes (see:
  4.1312 +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
  4.1313 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1314 +
  4.1315 +QHP_SECT_FILTER_ATTRS  =
  4.1316 +
  4.1317 +# The QHG_LOCATION tag can be used to specify the location of Qt's
  4.1318 +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
  4.1319 +# generated .qhp file.
  4.1320 +# This tag requires that the tag GENERATE_QHP is set to YES.
  4.1321 +
  4.1322 +QHG_LOCATION           =
  4.1323 +
  4.1324 +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
  4.1325 +# generated, together with the HTML files, they form an Eclipse help plugin. To
  4.1326 +# install this plugin and make it available under the help contents menu in
  4.1327 +# Eclipse, the contents of the directory containing the HTML and XML files needs
  4.1328 +# to be copied into the plugins directory of eclipse. The name of the directory
  4.1329 +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
  4.1330 +# After copying Eclipse needs to be restarted before the help appears.
  4.1331 +# The default value is: NO.
  4.1332 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1333 +
  4.1334 +GENERATE_ECLIPSEHELP   = NO
  4.1335 +
  4.1336 +# A unique identifier for the Eclipse help plugin. When installing the plugin
  4.1337 +# the directory name containing the HTML and XML files should also have this
  4.1338 +# name. Each documentation set should have its own identifier.
  4.1339 +# The default value is: org.doxygen.Project.
  4.1340 +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
  4.1341 +
  4.1342 +ECLIPSE_DOC_ID         = org.doxygen.Project
  4.1343 +
  4.1344 +# If you want full control over the layout of the generated HTML pages it might
  4.1345 +# be necessary to disable the index and replace it with your own. The
  4.1346 +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
  4.1347 +# of each HTML page. A value of NO enables the index and the value YES disables
  4.1348 +# it. Since the tabs in the index contain the same information as the navigation
  4.1349 +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
  4.1350 +# The default value is: NO.
  4.1351 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1352 +
  4.1353 +DISABLE_INDEX          = NO
  4.1354 +
  4.1355 +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
  4.1356 +# structure should be generated to display hierarchical information. If the tag
  4.1357 +# value is set to YES, a side panel will be generated containing a tree-like
  4.1358 +# index structure (just like the one that is generated for HTML Help). For this
  4.1359 +# to work a browser that supports JavaScript, DHTML, CSS and frames is required
  4.1360 +# (i.e. any modern browser). Windows users are probably better off using the
  4.1361 +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
  4.1362 +# further fine-tune the look of the index. As an example, the default style
  4.1363 +# sheet generated by doxygen has an example that shows how to put an image at
  4.1364 +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
  4.1365 +# the same information as the tab index, you could consider setting
  4.1366 +# DISABLE_INDEX to YES when enabling this option.
  4.1367 +# The default value is: NO.
  4.1368 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1369 +
  4.1370 +GENERATE_TREEVIEW      = NO
  4.1371 +
  4.1372 +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
  4.1373 +# doxygen will group on one line in the generated HTML documentation.
  4.1374 +#
  4.1375 +# Note that a value of 0 will completely suppress the enum values from appearing
  4.1376 +# in the overview section.
  4.1377 +# Minimum value: 0, maximum value: 20, default value: 4.
  4.1378 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1379 +
  4.1380 +ENUM_VALUES_PER_LINE   = 4
  4.1381 +
  4.1382 +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
  4.1383 +# to set the initial width (in pixels) of the frame in which the tree is shown.
  4.1384 +# Minimum value: 0, maximum value: 1500, default value: 250.
  4.1385 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1386 +
  4.1387 +TREEVIEW_WIDTH         = 250
  4.1388 +
  4.1389 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
  4.1390 +# external symbols imported via tag files in a separate window.
  4.1391 +# The default value is: NO.
  4.1392 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1393 +
  4.1394 +EXT_LINKS_IN_WINDOW    = NO
  4.1395 +
  4.1396 +# Use this tag to change the font size of LaTeX formulas included as images in
  4.1397 +# the HTML documentation. When you change the font size after a successful
  4.1398 +# doxygen run you need to manually remove any form_*.png images from the HTML
  4.1399 +# output directory to force them to be regenerated.
  4.1400 +# Minimum value: 8, maximum value: 50, default value: 10.
  4.1401 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1402 +
  4.1403 +FORMULA_FONTSIZE       = 10
  4.1404 +
  4.1405 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images
  4.1406 +# generated for formulas are transparent PNGs. Transparent PNGs are not
  4.1407 +# supported properly for IE 6.0, but are supported on all modern browsers.
  4.1408 +#
  4.1409 +# Note that when changing this option you need to delete any form_*.png files in
  4.1410 +# the HTML output directory before the changes have effect.
  4.1411 +# The default value is: YES.
  4.1412 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1413 +
  4.1414 +FORMULA_TRANSPARENT    = YES
  4.1415 +
  4.1416 +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
  4.1417 +# http://www.mathjax.org) which uses client side Javascript for the rendering
  4.1418 +# instead of using prerendered bitmaps. Use this if you do not have LaTeX
  4.1419 +# installed or if you want to formulas look prettier in the HTML output. When
  4.1420 +# enabled you may also need to install MathJax separately and configure the path
  4.1421 +# to it using the MATHJAX_RELPATH option.
  4.1422 +# The default value is: NO.
  4.1423 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1424 +
  4.1425 +USE_MATHJAX            = NO
  4.1426 +
  4.1427 +# When MathJax is enabled you can set the default output format to be used for
  4.1428 +# the MathJax output. See the MathJax site (see:
  4.1429 +# http://docs.mathjax.org/en/latest/output.html) for more details.
  4.1430 +# Possible values are: HTML-CSS (which is slower, but has the best
  4.1431 +# compatibility), NativeMML (i.e. MathML) and SVG.
  4.1432 +# The default value is: HTML-CSS.
  4.1433 +# This tag requires that the tag USE_MATHJAX is set to YES.
  4.1434 +
  4.1435 +MATHJAX_FORMAT         = HTML-CSS
  4.1436 +
  4.1437 +# When MathJax is enabled you need to specify the location relative to the HTML
  4.1438 +# output directory using the MATHJAX_RELPATH option. The destination directory
  4.1439 +# should contain the MathJax.js script. For instance, if the mathjax directory
  4.1440 +# is located at the same level as the HTML output directory, then
  4.1441 +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
  4.1442 +# Content Delivery Network so you can quickly see the result without installing
  4.1443 +# MathJax. However, it is strongly recommended to install a local copy of
  4.1444 +# MathJax from http://www.mathjax.org before deployment.
  4.1445 +# The default value is: http://cdn.mathjax.org/mathjax/latest.
  4.1446 +# This tag requires that the tag USE_MATHJAX is set to YES.
  4.1447 +
  4.1448 +MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
  4.1449 +
  4.1450 +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
  4.1451 +# extension names that should be enabled during MathJax rendering. For example
  4.1452 +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
  4.1453 +# This tag requires that the tag USE_MATHJAX is set to YES.
  4.1454 +
  4.1455 +MATHJAX_EXTENSIONS     =
  4.1456 +
  4.1457 +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
  4.1458 +# of code that will be used on startup of the MathJax code. See the MathJax site
  4.1459 +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
  4.1460 +# example see the documentation.
  4.1461 +# This tag requires that the tag USE_MATHJAX is set to YES.
  4.1462 +
  4.1463 +MATHJAX_CODEFILE       =
  4.1464 +
  4.1465 +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
  4.1466 +# the HTML output. The underlying search engine uses javascript and DHTML and
  4.1467 +# should work on any modern browser. Note that when using HTML help
  4.1468 +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
  4.1469 +# there is already a search function so this one should typically be disabled.
  4.1470 +# For large projects the javascript based search engine can be slow, then
  4.1471 +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
  4.1472 +# search using the keyboard; to jump to the search box use <access key> + S
  4.1473 +# (what the <access key> is depends on the OS and browser, but it is typically
  4.1474 +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
  4.1475 +# key> to jump into the search results window, the results can be navigated
  4.1476 +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
  4.1477 +# the search. The filter options can be selected when the cursor is inside the
  4.1478 +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
  4.1479 +# to select a filter and <Enter> or <escape> to activate or cancel the filter
  4.1480 +# option.
  4.1481 +# The default value is: YES.
  4.1482 +# This tag requires that the tag GENERATE_HTML is set to YES.
  4.1483 +
  4.1484 +SEARCHENGINE           = YES
  4.1485 +
  4.1486 +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
  4.1487 +# implemented using a web server instead of a web client using Javascript. There
  4.1488 +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
  4.1489 +# setting. When disabled, doxygen will generate a PHP script for searching and
  4.1490 +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
  4.1491 +# and searching needs to be provided by external tools. See the section
  4.1492 +# "External Indexing and Searching" for details.
  4.1493 +# The default value is: NO.
  4.1494 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1495 +
  4.1496 +SERVER_BASED_SEARCH    = NO
  4.1497 +
  4.1498 +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
  4.1499 +# script for searching. Instead the search results are written to an XML file
  4.1500 +# which needs to be processed by an external indexer. Doxygen will invoke an
  4.1501 +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
  4.1502 +# search results.
  4.1503 +#
  4.1504 +# Doxygen ships with an example indexer ( doxyindexer) and search engine
  4.1505 +# (doxysearch.cgi) which are based on the open source search engine library
  4.1506 +# Xapian (see: http://xapian.org/).
  4.1507 +#
  4.1508 +# See the section "External Indexing and Searching" for details.
  4.1509 +# The default value is: NO.
  4.1510 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1511 +
  4.1512 +EXTERNAL_SEARCH        = NO
  4.1513 +
  4.1514 +# The SEARCHENGINE_URL should point to a search engine hosted by a web server
  4.1515 +# which will return the search results when EXTERNAL_SEARCH is enabled.
  4.1516 +#
  4.1517 +# Doxygen ships with an example indexer ( doxyindexer) and search engine
  4.1518 +# (doxysearch.cgi) which are based on the open source search engine library
  4.1519 +# Xapian (see: http://xapian.org/). See the section "External Indexing and
  4.1520 +# Searching" for details.
  4.1521 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1522 +
  4.1523 +SEARCHENGINE_URL       =
  4.1524 +
  4.1525 +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
  4.1526 +# search data is written to a file for indexing by an external tool. With the
  4.1527 +# SEARCHDATA_FILE tag the name of this file can be specified.
  4.1528 +# The default file is: searchdata.xml.
  4.1529 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1530 +
  4.1531 +SEARCHDATA_FILE        = searchdata.xml
  4.1532 +
  4.1533 +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
  4.1534 +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
  4.1535 +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
  4.1536 +# projects and redirect the results back to the right project.
  4.1537 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1538 +
  4.1539 +EXTERNAL_SEARCH_ID     =
  4.1540 +
  4.1541 +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
  4.1542 +# projects other than the one defined by this configuration file, but that are
  4.1543 +# all added to the same external search index. Each project needs to have a
  4.1544 +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
  4.1545 +# to a relative location where the documentation can be found. The format is:
  4.1546 +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
  4.1547 +# This tag requires that the tag SEARCHENGINE is set to YES.
  4.1548 +
  4.1549 +EXTRA_SEARCH_MAPPINGS  =
  4.1550 +
  4.1551 +#---------------------------------------------------------------------------
  4.1552 +# Configuration options related to the LaTeX output
  4.1553 +#---------------------------------------------------------------------------
  4.1554 +
  4.1555 +# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
  4.1556 +# The default value is: YES.
  4.1557 +
  4.1558 +GENERATE_LATEX         = NO
  4.1559 +
  4.1560 +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
  4.1561 +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
  4.1562 +# it.
  4.1563 +# The default directory is: latex.
  4.1564 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1565 +
  4.1566 +LATEX_OUTPUT           = latex
  4.1567 +
  4.1568 +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
  4.1569 +# invoked.
  4.1570 +#
  4.1571 +# Note that when enabling USE_PDFLATEX this option is only used for generating
  4.1572 +# bitmaps for formulas in the HTML output, but not in the Makefile that is
  4.1573 +# written to the output directory.
  4.1574 +# The default file is: latex.
  4.1575 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1576 +
  4.1577 +LATEX_CMD_NAME         = latex
  4.1578 +
  4.1579 +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
  4.1580 +# index for LaTeX.
  4.1581 +# The default file is: makeindex.
  4.1582 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1583 +
  4.1584 +MAKEINDEX_CMD_NAME     = makeindex
  4.1585 +
  4.1586 +# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
  4.1587 +# documents. This may be useful for small projects and may help to save some
  4.1588 +# trees in general.
  4.1589 +# The default value is: NO.
  4.1590 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1591 +
  4.1592 +COMPACT_LATEX          = NO
  4.1593 +
  4.1594 +# The PAPER_TYPE tag can be used to set the paper type that is used by the
  4.1595 +# printer.
  4.1596 +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
  4.1597 +# 14 inches) and executive (7.25 x 10.5 inches).
  4.1598 +# The default value is: a4.
  4.1599 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1600 +
  4.1601 +PAPER_TYPE             = a4
  4.1602 +
  4.1603 +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
  4.1604 +# that should be included in the LaTeX output. To get the times font for
  4.1605 +# instance you can specify
  4.1606 +# EXTRA_PACKAGES=times
  4.1607 +# If left blank no extra packages will be included.
  4.1608 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1609 +
  4.1610 +EXTRA_PACKAGES         =
  4.1611 +
  4.1612 +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
  4.1613 +# generated LaTeX document. The header should contain everything until the first
  4.1614 +# chapter. If it is left blank doxygen will generate a standard header. See
  4.1615 +# section "Doxygen usage" for information on how to let doxygen write the
  4.1616 +# default header to a separate file.
  4.1617 +#
  4.1618 +# Note: Only use a user-defined header if you know what you are doing! The
  4.1619 +# following commands have a special meaning inside the header: $title,
  4.1620 +# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
  4.1621 +# replace them by respectively the title of the page, the current date and time,
  4.1622 +# only the current date, the version number of doxygen, the project name (see
  4.1623 +# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
  4.1624 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1625 +
  4.1626 +LATEX_HEADER           =
  4.1627 +
  4.1628 +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
  4.1629 +# generated LaTeX document. The footer should contain everything after the last
  4.1630 +# chapter. If it is left blank doxygen will generate a standard footer.
  4.1631 +#
  4.1632 +# Note: Only use a user-defined footer if you know what you are doing!
  4.1633 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1634 +
  4.1635 +LATEX_FOOTER           =
  4.1636 +
  4.1637 +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
  4.1638 +# other source files which should be copied to the LATEX_OUTPUT output
  4.1639 +# directory. Note that the files will be copied as-is; there are no commands or
  4.1640 +# markers available.
  4.1641 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1642 +
  4.1643 +LATEX_EXTRA_FILES      =
  4.1644 +
  4.1645 +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
  4.1646 +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
  4.1647 +# contain links (just like the HTML output) instead of page references. This
  4.1648 +# makes the output suitable for online browsing using a PDF viewer.
  4.1649 +# The default value is: YES.
  4.1650 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1651 +
  4.1652 +PDF_HYPERLINKS         = YES
  4.1653 +
  4.1654 +# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
  4.1655 +# the PDF file directly from the LaTeX files. Set this option to YES to get a
  4.1656 +# higher quality PDF documentation.
  4.1657 +# The default value is: YES.
  4.1658 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1659 +
  4.1660 +USE_PDFLATEX           = YES
  4.1661 +
  4.1662 +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
  4.1663 +# command to the generated LaTeX files. This will instruct LaTeX to keep running
  4.1664 +# if errors occur, instead of asking the user for help. This option is also used
  4.1665 +# when generating formulas in HTML.
  4.1666 +# The default value is: NO.
  4.1667 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1668 +
  4.1669 +LATEX_BATCHMODE        = NO
  4.1670 +
  4.1671 +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
  4.1672 +# index chapters (such as File Index, Compound Index, etc.) in the output.
  4.1673 +# The default value is: NO.
  4.1674 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1675 +
  4.1676 +LATEX_HIDE_INDICES     = NO
  4.1677 +
  4.1678 +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
  4.1679 +# code with syntax highlighting in the LaTeX output.
  4.1680 +#
  4.1681 +# Note that which sources are shown also depends on other settings such as
  4.1682 +# SOURCE_BROWSER.
  4.1683 +# The default value is: NO.
  4.1684 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1685 +
  4.1686 +LATEX_SOURCE_CODE      = NO
  4.1687 +
  4.1688 +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
  4.1689 +# bibliography, e.g. plainnat, or ieeetr. See
  4.1690 +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
  4.1691 +# The default value is: plain.
  4.1692 +# This tag requires that the tag GENERATE_LATEX is set to YES.
  4.1693 +
  4.1694 +LATEX_BIB_STYLE        = plain
  4.1695 +
  4.1696 +#---------------------------------------------------------------------------
  4.1697 +# Configuration options related to the RTF output
  4.1698 +#---------------------------------------------------------------------------
  4.1699 +
  4.1700 +# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
  4.1701 +# RTF output is optimized for Word 97 and may not look too pretty with other RTF
  4.1702 +# readers/editors.
  4.1703 +# The default value is: NO.
  4.1704 +
  4.1705 +GENERATE_RTF           = NO
  4.1706 +
  4.1707 +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
  4.1708 +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
  4.1709 +# it.
  4.1710 +# The default directory is: rtf.
  4.1711 +# This tag requires that the tag GENERATE_RTF is set to YES.
  4.1712 +
  4.1713 +RTF_OUTPUT             = rtf
  4.1714 +
  4.1715 +# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
  4.1716 +# documents. This may be useful for small projects and may help to save some
  4.1717 +# trees in general.
  4.1718 +# The default value is: NO.
  4.1719 +# This tag requires that the tag GENERATE_RTF is set to YES.
  4.1720 +
  4.1721 +COMPACT_RTF            = NO
  4.1722 +
  4.1723 +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
  4.1724 +# contain hyperlink fields. The RTF file will contain links (just like the HTML
  4.1725 +# output) instead of page references. This makes the output suitable for online
  4.1726 +# browsing using Word or some other Word compatible readers that support those
  4.1727 +# fields.
  4.1728 +#
  4.1729 +# Note: WordPad (write) and others do not support links.
  4.1730 +# The default value is: NO.
  4.1731 +# This tag requires that the tag GENERATE_RTF is set to YES.
  4.1732 +
  4.1733 +RTF_HYPERLINKS         = NO
  4.1734 +
  4.1735 +# Load stylesheet definitions from file. Syntax is similar to doxygen's config
  4.1736 +# file, i.e. a series of assignments. You only have to provide replacements,
  4.1737 +# missing definitions are set to their default value.
  4.1738 +#
  4.1739 +# See also section "Doxygen usage" for information on how to generate the
  4.1740 +# default style sheet that doxygen normally uses.
  4.1741 +# This tag requires that the tag GENERATE_RTF is set to YES.
  4.1742 +
  4.1743 +RTF_STYLESHEET_FILE    =
  4.1744 +
  4.1745 +# Set optional variables used in the generation of an RTF document. Syntax is
  4.1746 +# similar to doxygen's config file. A template extensions file can be generated
  4.1747 +# using doxygen -e rtf extensionFile.
  4.1748 +# This tag requires that the tag GENERATE_RTF is set to YES.
  4.1749 +
  4.1750 +RTF_EXTENSIONS_FILE    =
  4.1751 +
  4.1752 +#---------------------------------------------------------------------------
  4.1753 +# Configuration options related to the man page output
  4.1754 +#---------------------------------------------------------------------------
  4.1755 +
  4.1756 +# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
  4.1757 +# classes and files.
  4.1758 +# The default value is: NO.
  4.1759 +
  4.1760 +GENERATE_MAN           = NO
  4.1761 +
  4.1762 +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
  4.1763 +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
  4.1764 +# it. A directory man3 will be created inside the directory specified by
  4.1765 +# MAN_OUTPUT.
  4.1766 +# The default directory is: man.
  4.1767 +# This tag requires that the tag GENERATE_MAN is set to YES.
  4.1768 +
  4.1769 +MAN_OUTPUT             = man
  4.1770 +
  4.1771 +# The MAN_EXTENSION tag determines the extension that is added to the generated
  4.1772 +# man pages. In case the manual section does not start with a number, the number
  4.1773 +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
  4.1774 +# optional.
  4.1775 +# The default value is: .3.
  4.1776 +# This tag requires that the tag GENERATE_MAN is set to YES.
  4.1777 +
  4.1778 +MAN_EXTENSION          = .3
  4.1779 +
  4.1780 +# The MAN_SUBDIR tag determines the name of the directory created within
  4.1781 +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
  4.1782 +# MAN_EXTENSION with the initial . removed.
  4.1783 +# This tag requires that the tag GENERATE_MAN is set to YES.
  4.1784 +
  4.1785 +MAN_SUBDIR             =
  4.1786 +
  4.1787 +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
  4.1788 +# will generate one additional man file for each entity documented in the real
  4.1789 +# man page(s). These additional files only source the real man page, but without
  4.1790 +# them the man command would be unable to find the correct page.
  4.1791 +# The default value is: NO.
  4.1792 +# This tag requires that the tag GENERATE_MAN is set to YES.
  4.1793 +
  4.1794 +MAN_LINKS              = NO
  4.1795 +
  4.1796 +#---------------------------------------------------------------------------
  4.1797 +# Configuration options related to the XML output
  4.1798 +#---------------------------------------------------------------------------
  4.1799 +
  4.1800 +# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
  4.1801 +# captures the structure of the code including all documentation.
  4.1802 +# The default value is: NO.
  4.1803 +
  4.1804 +GENERATE_XML           = NO
  4.1805 +
  4.1806 +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
  4.1807 +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
  4.1808 +# it.
  4.1809 +# The default directory is: xml.
  4.1810 +# This tag requires that the tag GENERATE_XML is set to YES.
  4.1811 +
  4.1812 +XML_OUTPUT             = xml
  4.1813 +
  4.1814 +# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
  4.1815 +# listings (including syntax highlighting and cross-referencing information) to
  4.1816 +# the XML output. Note that enabling this will significantly increase the size
  4.1817 +# of the XML output.
  4.1818 +# The default value is: YES.
  4.1819 +# This tag requires that the tag GENERATE_XML is set to YES.
  4.1820 +
  4.1821 +XML_PROGRAMLISTING     = YES
  4.1822 +
  4.1823 +#---------------------------------------------------------------------------
  4.1824 +# Configuration options related to the DOCBOOK output
  4.1825 +#---------------------------------------------------------------------------
  4.1826 +
  4.1827 +# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
  4.1828 +# that can be used to generate PDF.
  4.1829 +# The default value is: NO.
  4.1830 +
  4.1831 +GENERATE_DOCBOOK       = NO
  4.1832 +
  4.1833 +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
  4.1834 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
  4.1835 +# front of it.
  4.1836 +# The default directory is: docbook.
  4.1837 +# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
  4.1838 +
  4.1839 +DOCBOOK_OUTPUT         = docbook
  4.1840 +
  4.1841 +#---------------------------------------------------------------------------
  4.1842 +# Configuration options for the AutoGen Definitions output
  4.1843 +#---------------------------------------------------------------------------
  4.1844 +
  4.1845 +# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
  4.1846 +# Definitions (see http://autogen.sf.net) file that captures the structure of
  4.1847 +# the code including all documentation. Note that this feature is still
  4.1848 +# experimental and incomplete at the moment.
  4.1849 +# The default value is: NO.
  4.1850 +
  4.1851 +GENERATE_AUTOGEN_DEF   = NO
  4.1852 +
  4.1853 +#---------------------------------------------------------------------------
  4.1854 +# Configuration options related to the Perl module output
  4.1855 +#---------------------------------------------------------------------------
  4.1856 +
  4.1857 +# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
  4.1858 +# file that captures the structure of the code including all documentation.
  4.1859 +#
  4.1860 +# Note that this feature is still experimental and incomplete at the moment.
  4.1861 +# The default value is: NO.
  4.1862 +
  4.1863 +GENERATE_PERLMOD       = NO
  4.1864 +
  4.1865 +# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
  4.1866 +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
  4.1867 +# output from the Perl module output.
  4.1868 +# The default value is: NO.
  4.1869 +# This tag requires that the tag GENERATE_PERLMOD is set to YES.
  4.1870 +
  4.1871 +PERLMOD_LATEX          = NO
  4.1872 +
  4.1873 +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
  4.1874 +# formatted so it can be parsed by a human reader. This is useful if you want to
  4.1875 +# understand what is going on. On the other hand, if this tag is set to NO the
  4.1876 +# size of the Perl module output will be much smaller and Perl will parse it
  4.1877 +# just the same.
  4.1878 +# The default value is: YES.
  4.1879 +# This tag requires that the tag GENERATE_PERLMOD is set to YES.
  4.1880 +
  4.1881 +PERLMOD_PRETTY         = YES
  4.1882 +
  4.1883 +# The names of the make variables in the generated doxyrules.make file are
  4.1884 +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
  4.1885 +# so different doxyrules.make files included by the same Makefile don't
  4.1886 +# overwrite each other's variables.
  4.1887 +# This tag requires that the tag GENERATE_PERLMOD is set to YES.
  4.1888 +
  4.1889 +PERLMOD_MAKEVAR_PREFIX =
  4.1890 +
  4.1891 +#---------------------------------------------------------------------------
  4.1892 +# Configuration options related to the preprocessor
  4.1893 +#---------------------------------------------------------------------------
  4.1894 +
  4.1895 +# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
  4.1896 +# C-preprocessor directives found in the sources and include files.
  4.1897 +# The default value is: YES.
  4.1898 +
  4.1899 +ENABLE_PREPROCESSING   = YES
  4.1900 +
  4.1901 +# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
  4.1902 +# in the source code. If set to NO only conditional compilation will be
  4.1903 +# performed. Macro expansion can be done in a controlled way by setting
  4.1904 +# EXPAND_ONLY_PREDEF to YES.
  4.1905 +# The default value is: NO.
  4.1906 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1907 +
  4.1908 +MACRO_EXPANSION        = NO
  4.1909 +
  4.1910 +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
  4.1911 +# the macro expansion is limited to the macros specified with the PREDEFINED and
  4.1912 +# EXPAND_AS_DEFINED tags.
  4.1913 +# The default value is: NO.
  4.1914 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1915 +
  4.1916 +EXPAND_ONLY_PREDEF     = NO
  4.1917 +
  4.1918 +# If the SEARCH_INCLUDES tag is set to YES the includes files in the
  4.1919 +# INCLUDE_PATH will be searched if a #include is found.
  4.1920 +# The default value is: YES.
  4.1921 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1922 +
  4.1923 +SEARCH_INCLUDES        = YES
  4.1924 +
  4.1925 +# The INCLUDE_PATH tag can be used to specify one or more directories that
  4.1926 +# contain include files that are not input files but should be processed by the
  4.1927 +# preprocessor.
  4.1928 +# This tag requires that the tag SEARCH_INCLUDES is set to YES.
  4.1929 +
  4.1930 +INCLUDE_PATH           =
  4.1931 +
  4.1932 +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
  4.1933 +# patterns (like *.h and *.hpp) to filter out the header-files in the
  4.1934 +# directories. If left blank, the patterns specified with FILE_PATTERNS will be
  4.1935 +# used.
  4.1936 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1937 +
  4.1938 +INCLUDE_FILE_PATTERNS  =
  4.1939 +
  4.1940 +# The PREDEFINED tag can be used to specify one or more macro names that are
  4.1941 +# defined before the preprocessor is started (similar to the -D option of e.g.
  4.1942 +# gcc). The argument of the tag is a list of macros of the form: name or
  4.1943 +# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
  4.1944 +# is assumed. To prevent a macro definition from being undefined via #undef or
  4.1945 +# recursively expanded use the := operator instead of the = operator.
  4.1946 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1947 +
  4.1948 +PREDEFINED             =
  4.1949 +
  4.1950 +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
  4.1951 +# tag can be used to specify a list of macro names that should be expanded. The
  4.1952 +# macro definition that is found in the sources will be used. Use the PREDEFINED
  4.1953 +# tag if you want to use a different macro definition that overrules the
  4.1954 +# definition found in the source code.
  4.1955 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1956 +
  4.1957 +EXPAND_AS_DEFINED      =
  4.1958 +
  4.1959 +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
  4.1960 +# remove all references to function-like macros that are alone on a line, have
  4.1961 +# an all uppercase name, and do not end with a semicolon. Such function macros
  4.1962 +# are typically used for boiler-plate code, and will confuse the parser if not
  4.1963 +# removed.
  4.1964 +# The default value is: YES.
  4.1965 +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
  4.1966 +
  4.1967 +SKIP_FUNCTION_MACROS   = YES
  4.1968 +
  4.1969 +#---------------------------------------------------------------------------
  4.1970 +# Configuration options related to external references
  4.1971 +#---------------------------------------------------------------------------
  4.1972 +
  4.1973 +# The TAGFILES tag can be used to specify one or more tag files. For each tag
  4.1974 +# file the location of the external documentation should be added. The format of
  4.1975 +# a tag file without this location is as follows:
  4.1976 +# TAGFILES = file1 file2 ...
  4.1977 +# Adding location for the tag files is done as follows:
  4.1978 +# TAGFILES = file1=loc1 "file2 = loc2" ...
  4.1979 +# where loc1 and loc2 can be relative or absolute paths or URLs. See the
  4.1980 +# section "Linking to external documentation" for more information about the use
  4.1981 +# of tag files.
  4.1982 +# Note: Each tag file must have a unique name (where the name does NOT include
  4.1983 +# the path). If a tag file is not located in the directory in which doxygen is
  4.1984 +# run, you must also specify the path to the tagfile here.
  4.1985 +
  4.1986 +TAGFILES               =
  4.1987 +
  4.1988 +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
  4.1989 +# tag file that is based on the input files it reads. See section "Linking to
  4.1990 +# external documentation" for more information about the usage of tag files.
  4.1991 +
  4.1992 +GENERATE_TAGFILE       =
  4.1993 +
  4.1994 +# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
  4.1995 +# class index. If set to NO only the inherited external classes will be listed.
  4.1996 +# The default value is: NO.
  4.1997 +
  4.1998 +ALLEXTERNALS           = NO
  4.1999 +
  4.2000 +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
  4.2001 +# the modules index. If set to NO, only the current project's groups will be
  4.2002 +# listed.
  4.2003 +# The default value is: YES.
  4.2004 +
  4.2005 +EXTERNAL_GROUPS        = YES
  4.2006 +
  4.2007 +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
  4.2008 +# the related pages index. If set to NO, only the current project's pages will
  4.2009 +# be listed.
  4.2010 +# The default value is: YES.
  4.2011 +
  4.2012 +EXTERNAL_PAGES         = YES
  4.2013 +
  4.2014 +# The PERL_PATH should be the absolute path and name of the perl script
  4.2015 +# interpreter (i.e. the result of 'which perl').
  4.2016 +# The default file (with absolute path) is: /usr/bin/perl.
  4.2017 +
  4.2018 +PERL_PATH              = /usr/bin/perl
  4.2019 +
  4.2020 +#---------------------------------------------------------------------------
  4.2021 +# Configuration options related to the dot tool
  4.2022 +#---------------------------------------------------------------------------
  4.2023 +
  4.2024 +# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
  4.2025 +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
  4.2026 +# NO turns the diagrams off. Note that this option also works with HAVE_DOT
  4.2027 +# disabled, but it is recommended to install and use dot, since it yields more
  4.2028 +# powerful graphs.
  4.2029 +# The default value is: YES.
  4.2030 +
  4.2031 +CLASS_DIAGRAMS         = YES
  4.2032 +
  4.2033 +# You can define message sequence charts within doxygen comments using the \msc
  4.2034 +# command. Doxygen will then run the mscgen tool (see:
  4.2035 +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
  4.2036 +# documentation. The MSCGEN_PATH tag allows you to specify the directory where
  4.2037 +# the mscgen tool resides. If left empty the tool is assumed to be found in the
  4.2038 +# default search path.
  4.2039 +
  4.2040 +MSCGEN_PATH            =
  4.2041 +
  4.2042 +# You can include diagrams made with dia in doxygen documentation. Doxygen will
  4.2043 +# then run dia to produce the diagram and insert it in the documentation. The
  4.2044 +# DIA_PATH tag allows you to specify the directory where the dia binary resides.
  4.2045 +# If left empty dia is assumed to be found in the default search path.
  4.2046 +
  4.2047 +DIA_PATH               =
  4.2048 +
  4.2049 +# If set to YES, the inheritance and collaboration graphs will hide inheritance
  4.2050 +# and usage relations if the target is undocumented or is not a class.
  4.2051 +# The default value is: YES.
  4.2052 +
  4.2053 +HIDE_UNDOC_RELATIONS   = YES
  4.2054 +
  4.2055 +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
  4.2056 +# available from the path. This tool is part of Graphviz (see:
  4.2057 +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
  4.2058 +# Bell Labs. The other options in this section have no effect if this option is
  4.2059 +# set to NO
  4.2060 +# The default value is: YES.
  4.2061 +
  4.2062 +HAVE_DOT               = NO
  4.2063 +
  4.2064 +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
  4.2065 +# to run in parallel. When set to 0 doxygen will base this on the number of
  4.2066 +# processors available in the system. You can set it explicitly to a value
  4.2067 +# larger than 0 to get control over the balance between CPU load and processing
  4.2068 +# speed.
  4.2069 +# Minimum value: 0, maximum value: 32, default value: 0.
  4.2070 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2071 +
  4.2072 +DOT_NUM_THREADS        = 0
  4.2073 +
  4.2074 +# When you want a differently looking font n the dot files that doxygen
  4.2075 +# generates you can specify the font name using DOT_FONTNAME. You need to make
  4.2076 +# sure dot is able to find the font, which can be done by putting it in a
  4.2077 +# standard location or by setting the DOTFONTPATH environment variable or by
  4.2078 +# setting DOT_FONTPATH to the directory containing the font.
  4.2079 +# The default value is: Helvetica.
  4.2080 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2081 +
  4.2082 +DOT_FONTNAME           = Helvetica
  4.2083 +
  4.2084 +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
  4.2085 +# dot graphs.
  4.2086 +# Minimum value: 4, maximum value: 24, default value: 10.
  4.2087 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2088 +
  4.2089 +DOT_FONTSIZE           = 10
  4.2090 +
  4.2091 +# By default doxygen will tell dot to use the default font as specified with
  4.2092 +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
  4.2093 +# the path where dot can find it using this tag.
  4.2094 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2095 +
  4.2096 +DOT_FONTPATH           =
  4.2097 +
  4.2098 +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
  4.2099 +# each documented class showing the direct and indirect inheritance relations.
  4.2100 +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
  4.2101 +# The default value is: YES.
  4.2102 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2103 +
  4.2104 +CLASS_GRAPH            = YES
  4.2105 +
  4.2106 +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
  4.2107 +# graph for each documented class showing the direct and indirect implementation
  4.2108 +# dependencies (inheritance, containment, and class references variables) of the
  4.2109 +# class with other documented classes.
  4.2110 +# The default value is: YES.
  4.2111 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2112 +
  4.2113 +COLLABORATION_GRAPH    = YES
  4.2114 +
  4.2115 +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
  4.2116 +# groups, showing the direct groups dependencies.
  4.2117 +# The default value is: YES.
  4.2118 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2119 +
  4.2120 +GROUP_GRAPHS           = YES
  4.2121 +
  4.2122 +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
  4.2123 +# collaboration diagrams in a style similar to the OMG's Unified Modeling
  4.2124 +# Language.
  4.2125 +# The default value is: NO.
  4.2126 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2127 +
  4.2128 +UML_LOOK               = NO
  4.2129 +
  4.2130 +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
  4.2131 +# class node. If there are many fields or methods and many nodes the graph may
  4.2132 +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
  4.2133 +# number of items for each type to make the size more manageable. Set this to 0
  4.2134 +# for no limit. Note that the threshold may be exceeded by 50% before the limit
  4.2135 +# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
  4.2136 +# but if the number exceeds 15, the total amount of fields shown is limited to
  4.2137 +# 10.
  4.2138 +# Minimum value: 0, maximum value: 100, default value: 10.
  4.2139 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2140 +
  4.2141 +UML_LIMIT_NUM_FIELDS   = 10
  4.2142 +
  4.2143 +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
  4.2144 +# collaboration graphs will show the relations between templates and their
  4.2145 +# instances.
  4.2146 +# The default value is: NO.
  4.2147 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2148 +
  4.2149 +TEMPLATE_RELATIONS     = NO
  4.2150 +
  4.2151 +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
  4.2152 +# YES then doxygen will generate a graph for each documented file showing the
  4.2153 +# direct and indirect include dependencies of the file with other documented
  4.2154 +# files.
  4.2155 +# The default value is: YES.
  4.2156 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2157 +
  4.2158 +INCLUDE_GRAPH          = YES
  4.2159 +
  4.2160 +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
  4.2161 +# set to YES then doxygen will generate a graph for each documented file showing
  4.2162 +# the direct and indirect include dependencies of the file with other documented
  4.2163 +# files.
  4.2164 +# The default value is: YES.
  4.2165 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2166 +
  4.2167 +INCLUDED_BY_GRAPH      = YES
  4.2168 +
  4.2169 +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
  4.2170 +# dependency graph for every global function or class method.
  4.2171 +#
  4.2172 +# Note that enabling this option will significantly increase the time of a run.
  4.2173 +# So in most cases it will be better to enable call graphs for selected
  4.2174 +# functions only using the \callgraph command.
  4.2175 +# The default value is: NO.
  4.2176 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2177 +
  4.2178 +CALL_GRAPH             = NO
  4.2179 +
  4.2180 +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
  4.2181 +# dependency graph for every global function or class method.
  4.2182 +#
  4.2183 +# Note that enabling this option will significantly increase the time of a run.
  4.2184 +# So in most cases it will be better to enable caller graphs for selected
  4.2185 +# functions only using the \callergraph command.
  4.2186 +# The default value is: NO.
  4.2187 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2188 +
  4.2189 +CALLER_GRAPH           = NO
  4.2190 +
  4.2191 +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
  4.2192 +# hierarchy of all classes instead of a textual one.
  4.2193 +# The default value is: YES.
  4.2194 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2195 +
  4.2196 +GRAPHICAL_HIERARCHY    = YES
  4.2197 +
  4.2198 +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
  4.2199 +# dependencies a directory has on other directories in a graphical way. The
  4.2200 +# dependency relations are determined by the #include relations between the
  4.2201 +# files in the directories.
  4.2202 +# The default value is: YES.
  4.2203 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2204 +
  4.2205 +DIRECTORY_GRAPH        = YES
  4.2206 +
  4.2207 +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
  4.2208 +# generated by dot.
  4.2209 +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
  4.2210 +# to make the SVG files visible in IE 9+ (other browsers do not have this
  4.2211 +# requirement).
  4.2212 +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
  4.2213 +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
  4.2214 +# gif:cairo:gd, gif:gd, gif:gd:gd and svg.
  4.2215 +# The default value is: png.
  4.2216 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2217 +
  4.2218 +DOT_IMAGE_FORMAT       = png
  4.2219 +
  4.2220 +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
  4.2221 +# enable generation of interactive SVG images that allow zooming and panning.
  4.2222 +#
  4.2223 +# Note that this requires a modern browser other than Internet Explorer. Tested
  4.2224 +# and working are Firefox, Chrome, Safari, and Opera.
  4.2225 +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
  4.2226 +# the SVG files visible. Older versions of IE do not have SVG support.
  4.2227 +# The default value is: NO.
  4.2228 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2229 +
  4.2230 +INTERACTIVE_SVG        = NO
  4.2231 +
  4.2232 +# The DOT_PATH tag can be used to specify the path where the dot tool can be
  4.2233 +# found. If left blank, it is assumed the dot tool can be found in the path.
  4.2234 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2235 +
  4.2236 +DOT_PATH               =
  4.2237 +
  4.2238 +# The DOTFILE_DIRS tag can be used to specify one or more directories that
  4.2239 +# contain dot files that are included in the documentation (see the \dotfile
  4.2240 +# command).
  4.2241 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2242 +
  4.2243 +DOTFILE_DIRS           =
  4.2244 +
  4.2245 +# The MSCFILE_DIRS tag can be used to specify one or more directories that
  4.2246 +# contain msc files that are included in the documentation (see the \mscfile
  4.2247 +# command).
  4.2248 +
  4.2249 +MSCFILE_DIRS           =
  4.2250 +
  4.2251 +# The DIAFILE_DIRS tag can be used to specify one or more directories that
  4.2252 +# contain dia files that are included in the documentation (see the \diafile
  4.2253 +# command).
  4.2254 +
  4.2255 +DIAFILE_DIRS           =
  4.2256 +
  4.2257 +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
  4.2258 +# that will be shown in the graph. If the number of nodes in a graph becomes
  4.2259 +# larger than this value, doxygen will truncate the graph, which is visualized
  4.2260 +# by representing a node as a red box. Note that doxygen if the number of direct
  4.2261 +# children of the root node in a graph is already larger than
  4.2262 +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
  4.2263 +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
  4.2264 +# Minimum value: 0, maximum value: 10000, default value: 50.
  4.2265 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2266 +
  4.2267 +DOT_GRAPH_MAX_NODES    = 50
  4.2268 +
  4.2269 +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
  4.2270 +# generated by dot. A depth value of 3 means that only nodes reachable from the
  4.2271 +# root by following a path via at most 3 edges will be shown. Nodes that lay
  4.2272 +# further from the root node will be omitted. Note that setting this option to 1
  4.2273 +# or 2 may greatly reduce the computation time needed for large code bases. Also
  4.2274 +# note that the size of a graph can be further restricted by
  4.2275 +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
  4.2276 +# Minimum value: 0, maximum value: 1000, default value: 0.
  4.2277 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2278 +
  4.2279 +MAX_DOT_GRAPH_DEPTH    = 0
  4.2280 +
  4.2281 +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
  4.2282 +# background. This is disabled by default, because dot on Windows does not seem
  4.2283 +# to support this out of the box.
  4.2284 +#
  4.2285 +# Warning: Depending on the platform used, enabling this option may lead to
  4.2286 +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
  4.2287 +# read).
  4.2288 +# The default value is: NO.
  4.2289 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2290 +
  4.2291 +DOT_TRANSPARENT        = NO
  4.2292 +
  4.2293 +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
  4.2294 +# files in one run (i.e. multiple -o and -T options on the command line). This
  4.2295 +# makes dot run faster, but since only newer versions of dot (>1.8.10) support
  4.2296 +# this, this feature is disabled by default.
  4.2297 +# The default value is: NO.
  4.2298 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2299 +
  4.2300 +DOT_MULTI_TARGETS      = YES
  4.2301 +
  4.2302 +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
  4.2303 +# explaining the meaning of the various boxes and arrows in the dot generated
  4.2304 +# graphs.
  4.2305 +# The default value is: YES.
  4.2306 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2307 +
  4.2308 +GENERATE_LEGEND        = YES
  4.2309 +
  4.2310 +# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
  4.2311 +# files that are used to generate the various graphs.
  4.2312 +# The default value is: YES.
  4.2313 +# This tag requires that the tag HAVE_DOT is set to YES.
  4.2314 +
  4.2315 +DOT_CLEANUP            = YES
     5.1 --- a/configure.ac	Mon Dec 30 09:52:07 2019 +0100
     5.2 +++ b/configure.ac	Mon Dec 30 09:52:44 2019 +0100
     5.3 @@ -28,6 +28,7 @@
     5.4  
     5.5  # the package version must match the macros in ucx.h
     5.6  # the lib version must follow the libtool versioning convention
     5.7 +AC_PREREQ([2.60])
     5.8  AC_INIT([ucx], [2.1.0], [olaf.wintermann@gmail.com])
     5.9  AC_SUBST([UCX_LIB_VERSION], [4:0:1])
    5.10  
    5.11 @@ -44,17 +45,14 @@
    5.12  # we are compiling a library
    5.13  LT_INIT
    5.14  
    5.15 -# we are dealing with C source code
    5.16 -AC_PROG_CC
    5.17 +# we want c11, and may fall back to c99
    5.18 +AC_PROG_CC_C99
    5.19  
    5.20  # we want to support automake < 1.14, so we need this deprecated macro
    5.21  # it tests, whether the compiler allows -c and -o simultaneously
    5.22  # in modern versions of autoconf, this is done by AC_PROG_CC
    5.23  AM_PROG_CC_C_O
    5.24  
    5.25 -# we require the current C standard
    5.26 -AC_PROG_CC_STDC
    5.27 -
    5.28  # where to place config macros
    5.29  AC_CONFIG_HEADERS([config.h])
    5.30  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/docs/src/CMakeLists.txt	Mon Dec 30 09:52:44 2019 +0100
     6.3 @@ -0,0 +1,63 @@
     6.4 +#
     6.5 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 +#
     6.7 +# Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved.
     6.8 +#
     6.9 +# Redistribution and use in source and binary forms, with or without
    6.10 +# modification, are permitted provided that the following conditions are met:
    6.11 +#
    6.12 +#   1. Redistributions of source code must retain the above copyright
    6.13 +#      notice, this list of conditions and the following disclaimer.
    6.14 +#
    6.15 +#   2. Redistributions in binary form must reproduce the above copyright
    6.16 +#      notice, this list of conditions and the following disclaimer in the
    6.17 +#      documentation and/or other materials provided with the distribution.
    6.18 +#
    6.19 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    6.20 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    6.21 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    6.22 +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    6.23 +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    6.24 +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    6.25 +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    6.26 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    6.27 +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    6.28 +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    6.29 +# POSSIBILITY OF SUCH DAMAGE.
    6.30 +#
    6.31 +
    6.32 +set(PANDOC_DESTDIR ${CMAKE_BINARY_DIR}/docs/web)
    6.33 +set(PANDOC_ARGS -c ucx.css -B header.html -A footer.html -T 'UAP Common Extensions')
    6.34 +set(PANDOC_SRC index.md license.md modules.md install.md)
    6.35 +set(LOGO_PATH ../../uaplogo.png)
    6.36 +
    6.37 +if (NOT EXISTS ${PANDOC_EXECUTABLE})
    6.38 +    find_program(PANDOC_EXECUTABLE pandoc)
    6.39 +    if(NOT EXISTS ${PANDOC_EXECUTABLE})
    6.40 +        message(WARNING Pandoc not found, docs-html target will not be generated.)
    6.41 +        return()
    6.42 +    endif()
    6.43 +endif()
    6.44 +
    6.45 +message(STATUS "HTML Documentation will be generated at: ${PANDOC_DESTDIR}.")
    6.46 +file(MAKE_DIRECTORY ${PANDOC_DESTDIR})
    6.47 +
    6.48 +foreach(source_file ${PANDOC_SRC})
    6.49 +    string(REPLACE .md .html dest_file ${source_file})
    6.50 +    string(PREPEND dest_file "${PANDOC_DESTDIR}/")
    6.51 +    list(APPEND PANDOC_DEST ${dest_file})
    6.52 +    add_custom_command(
    6.53 +            OUTPUT ${dest_file}
    6.54 +            COMMAND ${PANDOC_EXECUTABLE} ${PANDOC_ARGS}  -o ${dest_file} ${source_file}
    6.55 +            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    6.56 +            MAIN_DEPENDENCY ${source_file}
    6.57 +    )
    6.58 +endforeach()
    6.59 +
    6.60 +add_custom_target(docs-html
    6.61 +        COMMAND ${CMAKE_COMMAND} -E copy ucx.css ${PANDOC_DESTDIR}/ucx.css
    6.62 +        COMMAND ${CMAKE_COMMAND} -E copy ${LOGO_PATH} ${PANDOC_DESTDIR}/uaplogo.png
    6.63 +        DEPENDS ${PANDOC_DEST}
    6.64 +        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    6.65 +        COMMENT "Generating HTML documentation with pandoc."
    6.66 +)
     7.1 --- a/docs/src/index.md	Mon Dec 30 09:52:07 2019 +0100
     7.2 +++ b/docs/src/index.md	Mon Dec 30 09:52:44 2019 +0100
     7.3 @@ -25,3 +25,40 @@
     7.4  
     7.5  Olaf Wintermann
     7.6  [&lt;olaf.wintermann@gmail.com&gt;](mailto:olaf.wintermann@gmail.com)
     7.7 +
     7.8 +Changelog
     7.9 +---------
    7.10 +
    7.11 +### Version 2.1 - 2019-12-30
    7.12 + 
    7.13 + * adds string replace functions
    7.14 + * adds set operations for ` UcxList` and `UcxMap`
    7.15 + * adds `sstrcaseprefix()` and `sstrcasesuffix()`
    7.16 + * improves Doxygen documentation in ucx/string.h
    7.17 + * adds `UcxArray` data type
    7.18 + * adds support for CMake builds, but main build system is still autotools
    7.19 + 
    7.20 +### Version 2.0 - 2018-12-28
    7.21 + 
    7.22 + * some uncritical bug fixes
    7.23 + * overflow of `sstrnlen` now returns `SIZE_MAX` instead of zero
    7.24 + * adds `scstr_t` - a `const char*` variant for sstr_t
    7.25 + * renames utility compare functions
    7.26 + 
    7.27 +### Version 1.1 - 2018-05-14
    7.28 + 
    7.29 + * adds missing 32 bit support to integer overflow checks
    7.30 + * adds `ucx_buffer_to_sstr()` macro
    7.31 + * adds `ucx_avl_free_content()`
    7.32 + * adds some more compare and distance functions in utils.h
    7.33 + * adds `SFMT()` and `PRIsstr` convenience macros
    7.34 + * destructor functions for `*_free_content()` functions are now optional
    7.35 + 
    7.36 +### Version 1.0.1 - 2018-01-21
    7.37 + 
    7.38 + * some bug fixes
    7.39 + * adds integer overflow checks
    7.40 + 
    7.41 +### Version 1.0 - 2017-10-28
    7.42 + 
    7.43 + * first stable version of UCX released
     8.1 --- a/docs/src/modules.md	Mon Dec 30 09:52:07 2019 +0100
     8.2 +++ b/docs/src/modules.md	Mon Dec 30 09:52:44 2019 +0100
     8.3 @@ -61,22 +61,17 @@
     8.4  a standard dynamic C array (pointer+length) as basis.
     8.5  
     8.6  ```C
     8.7 -#include <stdio.h>
     8.8 -#include <ucx/array.h>
     8.9 -#include <ucx/string.h>
    8.10 -#include <ucx/utils.h>
    8.11 -
    8.12 -UcxArray remove_duplicates(sstr_t* array, size_t arrlen) {
    8.13 +UcxArray* create_unique(sstr_t* array, size_t arrlen) {
    8.14      // worst case is no duplicates, hence the capacity is set to arrlen
    8.15 -    UcxArray result = ucx_array_new(arrlen, sizeof(sstr_t));
    8.16 +    UcxArray* result = ucx_array_new(arrlen, sizeof(sstr_t));
    8.17      // only append elements, if they are not already present in the array
    8.18      for (size_t i = 0 ; i < arrlen ; ++i) {
    8.19          if (!ucx_array_contains(result, array+i, ucx_cmp_sstr, NULL)) {
    8.20 -            ucx_array_append(&result, array+i);
    8.21 +            ucx_array_append_from(result, array+i, 1);
    8.22          }
    8.23      }
    8.24      // make the array as small as possible
    8.25 -    ucx_array_shrink(&result);
    8.26 +    ucx_array_shrink(result);
    8.27      return result;
    8.28  }
    8.29  
    8.30 @@ -85,16 +80,36 @@
    8.31  sstr_t* array = /* some standard array of strings */
    8.32  size_t arrlen = /* the length of the array */
    8.33  
    8.34 -UcxArray result = remove_duplicates(array,arrlen);
    8.35 +UcxArray* result = create_unique(array,arrlen);
    8.36  
    8.37  /* Iterate over the array and print the elements */
    8.38 -for (size_t i = 0 ; i < result.size ; i++) {
    8.39 -    sstr_t s = ucx_array_at_typed(sstr_t, result, i);
    8.40 -    printf("%" PRIsstr "\n", SFMT(s));
    8.41 +sstr_t* unique = result->data;
    8.42 +for (size_t i = 0 ; i < result->size ; i++) {
    8.43 +    printf("%" PRIsstr "\n", SFMT(unique[i]));
    8.44  }
    8.45  
    8.46  /* Free the array. */
    8.47 -ucx_array_free(&result);
    8.48 +ucx_array_free(result);
    8.49 +```
    8.50 +### Preventing out of bounds writes
    8.51 +
    8.52 +The functions `ucx_array_reserve()`, `ucx_array_resize()`, `ucx_array_grow()`,
    8.53 +and `ucx_array_shrink()` allow easy management of the array capacity.
    8.54 +Imagine you want to add `n` elements to an array. If your `n` elements are
    8.55 +already somewhere else consecutively in memory, you can use
    8.56 +`ucx_array_append_from()` and benefit from the autogrow facility in this family
    8.57 +of functions. Otherwise, you can ask the array to have enough capacity for
    8.58 +holding additional `n` elements.
    8.59 +
    8.60 +```C
    8.61 +size_t n = // ... elements to add
    8.62 +if (ucx_array_grow(array, n)) {
    8.63 +   fprintf(stderr, "Cannot add %zu elements to the array.\n", n);
    8.64 +   return 1;
    8.65 +}
    8.66 +for (size_t i = 0 ; i < n ; i++) {
    8.67 +    ((int*)array->data)[array->size++] = 80;
    8.68 +}
    8.69  ```
    8.70  
    8.71  ## AVL Tree
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/CMakeLists.txt	Mon Dec 30 09:52:44 2019 +0100
     9.3 @@ -0,0 +1,50 @@
     9.4 +set(sources
     9.5 +        allocator.c
     9.6 +        array.c
     9.7 +        avl.c
     9.8 +        buffer.c
     9.9 +        list.c
    9.10 +        logging.c
    9.11 +        map.c
    9.12 +        mempool.c
    9.13 +        properties.c
    9.14 +        stack.c
    9.15 +        string.c
    9.16 +        test.c
    9.17 +        ucx.c
    9.18 +        utils.c
    9.19 +)
    9.20 +set(headers
    9.21 +        ucx/allocator.h
    9.22 +        ucx/array.h
    9.23 +        ucx/avl.h
    9.24 +        ucx/buffer.h
    9.25 +        ucx/list.h
    9.26 +        ucx/logging.h
    9.27 +        ucx/map.h
    9.28 +        ucx/mempool.h
    9.29 +        ucx/properties.h
    9.30 +        ucx/stack.h
    9.31 +        ucx/string.h
    9.32 +        ucx/test.h
    9.33 +        ucx/ucx.h
    9.34 +        ucx/utils.h
    9.35 +)
    9.36 +
    9.37 +add_library(ucx SHARED ${sources})
    9.38 +add_library(ucx_static STATIC ${sources})
    9.39 +
    9.40 +target_include_directories(ucx PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    9.41 +target_include_directories(ucx_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    9.42 +
    9.43 +set_target_properties(ucx PROPERTIES SOVERSION 3 VERSION 3.1.0)
    9.44 +set_target_properties(ucx_static PROPERTIES VERSION ${CMAKE_PROJECT_VERSION})
    9.45 +
    9.46 +# it is sufficient to specify the headers for one of the targets
    9.47 +set_target_properties(ucx PROPERTIES PUBLIC_HEADER "${headers}")
    9.48 +
    9.49 +include(GNUInstallDirs)
    9.50 +install(TARGETS ucx ucx_static
    9.51 +        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    9.52 +        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    9.53 +        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ucx)
    9.54 \ No newline at end of file
    10.1 --- a/src/array.c	Mon Dec 30 09:52:07 2019 +0100
    10.2 +++ b/src/array.c	Mon Dec 30 09:52:44 2019 +0100
    10.3 @@ -70,7 +70,7 @@
    10.4  }
    10.5  
    10.6  int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity,
    10.7 -    size_t elmsize, size_t index, ...) {
    10.8 +    size_t elmsize, size_t index, void* data) {
    10.9      
   10.10      if(!alloc || !capacity || !array) {
   10.11          errno = EINVAL;
   10.12 @@ -104,16 +104,18 @@
   10.13      
   10.14      char* dest = *array;
   10.15      dest += elmsize*index;
   10.16 -
   10.17 -    va_list ap;
   10.18 -    va_start(ap, index);
   10.19 -    int elem = va_arg(ap, int);    
   10.20 -    memcpy(dest, &elem, elmsize);
   10.21 -    va_end(ap);
   10.22 +    memcpy(dest, data, elmsize);
   10.23      
   10.24      return 0;
   10.25  }
   10.26  
   10.27 +int ucx_array_util_setptr_a(UcxAllocator* alloc, void** array, size_t* capacity,
   10.28 +    size_t index, void* data) {
   10.29 +    
   10.30 +    return ucx_array_util_set_a(alloc, array, capacity, sizeof(void*),
   10.31 +            index, &data);
   10.32 +}
   10.33 +
   10.34  UcxArray* ucx_array_new(size_t capacity, size_t elemsize) {
   10.35      return ucx_array_new_a(capacity, elemsize, ucx_default_allocator());
   10.36  }
   10.37 @@ -254,33 +256,6 @@
   10.38      return 0;
   10.39  }
   10.40  
   10.41 -int ucx_array_appendv(UcxArray *array, ...) {
   10.42 -    va_list ap;
   10.43 -    va_start(ap, array);
   10.44 -    int elem = va_arg(ap, int);
   10.45 -    int ret = ucx_array_append_from(array, &elem, 1);
   10.46 -    va_end(ap);
   10.47 -    return ret;
   10.48 -}
   10.49 -
   10.50 -int ucx_array_prependv(UcxArray *array, ...) {
   10.51 -    va_list ap;
   10.52 -    va_start(ap, array);
   10.53 -    int elem = va_arg(ap, int);
   10.54 -    int ret = ucx_array_prepend_from(array, &elem, 1);
   10.55 -    va_end(ap);
   10.56 -    return ret;
   10.57 -}
   10.58 -
   10.59 -int ucx_array_setv(UcxArray *array, size_t index, ...) {
   10.60 -    va_list ap;
   10.61 -    va_start(ap, index);
   10.62 -    int elem = va_arg(ap, int);
   10.63 -    int ret = ucx_array_set_from(array, index, &elem, 1);
   10.64 -    va_end(ap);
   10.65 -    return ret;
   10.66 -}
   10.67 -
   10.68  int ucx_array_concat(UcxArray *array1, const UcxArray *array2) {
   10.69      
   10.70      if (array1->elemsize != array2->elemsize)
   10.71 @@ -404,7 +379,7 @@
   10.72  };
   10.73  
   10.74  static int cmp_func_swap_args(void *data, const void *x, const void *y) {
   10.75 -    cmpfnc_swapargs_info* info = data;
   10.76 +    struct cmpfnc_swapargs_info* info = data;
   10.77      return info->func(x, y, info->data);
   10.78  }
   10.79  
   10.80 @@ -486,3 +461,7 @@
   10.81          }
   10.82      }
   10.83  }
   10.84 +
   10.85 +int ucx_array_grow(UcxArray* array, size_t count) {
   10.86 +    return ucx_array_reserve(array, array->size+count);
   10.87 +}
    11.1 --- a/src/list.c	Mon Dec 30 09:52:07 2019 +0100
    11.2 +++ b/src/list.c	Mon Dec 30 09:52:44 2019 +0100
    11.3 @@ -28,11 +28,11 @@
    11.4  
    11.5  #include "ucx/list.h"
    11.6  
    11.7 -UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) {
    11.8 +UcxList *ucx_list_clone(const UcxList *l, copy_func fnc, void *data) {
    11.9      return ucx_list_clone_a(ucx_default_allocator(), l, fnc, data);
   11.10  }
   11.11  
   11.12 -UcxList *ucx_list_clone_a(UcxAllocator *alloc, UcxList *l,
   11.13 +UcxList *ucx_list_clone_a(UcxAllocator *alloc, const UcxList *l,
   11.14          copy_func fnc, void *data) {
   11.15      UcxList *ret = NULL;
   11.16      while (l) {
   11.17 @@ -172,7 +172,8 @@
   11.18      return (UcxList*)(index == 0 ? e : NULL);
   11.19  }
   11.20  
   11.21 -ssize_t ucx_list_find(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
   11.22 +ssize_t ucx_list_find(const UcxList *l, void *elem,
   11.23 +        cmp_func fnc, void *cmpdata) {
   11.24      ssize_t index = 0;
   11.25      UCX_FOREACH(e, l) {
   11.26          if (fnc) {
   11.27 @@ -189,7 +190,8 @@
   11.28      return -1;
   11.29  }
   11.30  
   11.31 -int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
   11.32 +int ucx_list_contains(const UcxList *l, void *elem,
   11.33 +        cmp_func fnc, void *cmpdata) {
   11.34      return ucx_list_find(l, elem, fnc, cmpdata) > -1;
   11.35  }
   11.36  
   11.37 @@ -334,3 +336,93 @@
   11.38      alfree(alloc, e);
   11.39      return l;
   11.40  }
   11.41 +
   11.42 +
   11.43 +static UcxList* ucx_list_setoperation_a(UcxAllocator *allocator,
   11.44 +        UcxList const *left, UcxList const *right,
   11.45 +        cmp_func cmpfnc, void* cmpdata,
   11.46 +        copy_func cpfnc, void* cpdata,
   11.47 +        int op) {
   11.48 +    
   11.49 +    UcxList *res = NULL;
   11.50 +    UcxList *cur = NULL;
   11.51 +    const UcxList *src = left;
   11.52 +    
   11.53 +    do {
   11.54 +        UCX_FOREACH(node, src) {
   11.55 +            void* elem = node->data;
   11.56 +            if (
   11.57 +                (op == 0 && !ucx_list_contains(res, elem, cmpfnc, cmpdata)) ||
   11.58 +                (op == 1 && ucx_list_contains(right, elem, cmpfnc, cmpdata)) ||
   11.59 +                (op == 2 && !ucx_list_contains(right, elem, cmpfnc, cmpdata))) {
   11.60 +                UcxList *nl = almalloc(allocator, sizeof(UcxList));
   11.61 +                nl->prev = cur;
   11.62 +                nl->next = NULL;
   11.63 +                if (cpfnc) {
   11.64 +                    nl->data = cpfnc(elem, cpdata);
   11.65 +                } else {
   11.66 +                    nl->data = elem;
   11.67 +                }
   11.68 +                if (cur != NULL)
   11.69 +                    cur->next = nl;
   11.70 +                cur = nl;
   11.71 +                if (res == NULL)
   11.72 +                    res = cur;
   11.73 +            }
   11.74 +        }
   11.75 +        if (op == 0 && src == left)
   11.76 +            src = right;
   11.77 +        else
   11.78 +            src = NULL;
   11.79 +    } while (src != NULL);
   11.80 +    
   11.81 +    return res;
   11.82 +}
   11.83 +
   11.84 +UcxList* ucx_list_union(UcxList const *left, UcxList const *right,
   11.85 +        cmp_func cmpfnc, void* cmpdata,
   11.86 +        copy_func cpfnc, void* cpdata) {
   11.87 +    return ucx_list_union_a(ucx_default_allocator(),
   11.88 +            left, right, cmpfnc, cmpdata, cpfnc, cpdata);
   11.89 +}
   11.90 +
   11.91 +UcxList* ucx_list_union_a(UcxAllocator *allocator,
   11.92 +        UcxList const *left, UcxList const *right,
   11.93 +        cmp_func cmpfnc, void* cmpdata,
   11.94 +        copy_func cpfnc, void* cpdata) {
   11.95 +    
   11.96 +    return ucx_list_setoperation_a(allocator, left, right,
   11.97 +            cmpfnc, cmpdata, cpfnc, cpdata, 0);
   11.98 +}
   11.99 +
  11.100 +UcxList* ucx_list_intersection(UcxList const *left, UcxList const *right,
  11.101 +        cmp_func cmpfnc, void* cmpdata,
  11.102 +        copy_func cpfnc, void* cpdata) {
  11.103 +    return ucx_list_intersection_a(ucx_default_allocator(), left, right,
  11.104 +            cmpfnc, cmpdata, cpfnc, cpdata);
  11.105 +}
  11.106 +
  11.107 +UcxList* ucx_list_intersection_a(UcxAllocator *allocator,
  11.108 +        UcxList const *left, UcxList const *right,
  11.109 +        cmp_func cmpfnc, void* cmpdata,
  11.110 +        copy_func cpfnc, void* cpdata) {
  11.111 +    
  11.112 +    return ucx_list_setoperation_a(allocator, left, right,
  11.113 +            cmpfnc, cmpdata, cpfnc, cpdata, 1);
  11.114 +}
  11.115 +
  11.116 +UcxList* ucx_list_difference(UcxList const *left, UcxList const *right,
  11.117 +        cmp_func cmpfnc, void* cmpdata,
  11.118 +        copy_func cpfnc, void* cpdata) {
  11.119 +    return ucx_list_difference_a(ucx_default_allocator(), left, right,
  11.120 +            cmpfnc, cmpdata, cpfnc, cpdata);
  11.121 +}
  11.122 +
  11.123 +UcxList* ucx_list_difference_a(UcxAllocator *allocator,
  11.124 +        UcxList const *left, UcxList const *right,
  11.125 +        cmp_func cmpfnc, void* cmpdata,
  11.126 +        copy_func cpfnc, void* cpdata) {
  11.127 +    
  11.128 +    return ucx_list_setoperation_a(allocator, left, right,
  11.129 +            cmpfnc, cmpdata, cpfnc, cpdata, 2);
  11.130 +}
    12.1 --- a/src/logging.c	Mon Dec 30 09:52:07 2019 +0100
    12.2 +++ b/src/logging.c	Mon Dec 30 09:52:44 2019 +0100
    12.3 @@ -91,6 +91,10 @@
    12.4              k += strftime(msg+k, 128, logger->dateformat, localtime(&now));
    12.5          }
    12.6          if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
    12.7 +            char *fpart = strrchr(file, '/');
    12.8 +            if (fpart) file = fpart+1;
    12.9 +            fpart = strrchr(file, '\\');
   12.10 +            if (fpart) file = fpart+1;
   12.11              n = strlen(file);
   12.12              memcpy(msg+k, file, n);
   12.13              k += n;
    13.1 --- a/src/map.c	Mon Dec 30 09:52:07 2019 +0100
    13.2 +++ b/src/map.c	Mon Dec 30 09:52:44 2019 +0100
    13.3 @@ -103,7 +103,7 @@
    13.4      map->count = 0;
    13.5  }
    13.6  
    13.7 -int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data) {
    13.8 +int ucx_map_copy(UcxMap const *from, UcxMap *to, copy_func fnc, void *data) {
    13.9      UcxMapIterator i = ucx_map_iterator(from);
   13.10      void *value;
   13.11      UCX_MAP_FOREACH(key, value, i) {
   13.12 @@ -114,9 +114,14 @@
   13.13      return 0;
   13.14  }
   13.15  
   13.16 -UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
   13.17 +UcxMap *ucx_map_clone(UcxMap const *map, copy_func fnc, void *data) {
   13.18 +    return ucx_map_clone_a(ucx_default_allocator(), map, fnc, data);
   13.19 +}
   13.20 +
   13.21 +UcxMap *ucx_map_clone_a(UcxAllocator *allocator,
   13.22 +        UcxMap const *map, copy_func fnc, void *data) {
   13.23      size_t bs = (map->count * 5) >> 1;
   13.24 -    UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
   13.25 +    UcxMap *newmap = ucx_map_new_a(allocator, bs > map->size ? bs : map->size);
   13.26      if (!newmap) {
   13.27          return NULL;
   13.28      }
   13.29 @@ -235,8 +240,8 @@
   13.30      return NULL;
   13.31  }
   13.32  
   13.33 -void *ucx_map_get(UcxMap *map, UcxKey key) {
   13.34 -    return ucx_map_get_and_remove(map, key, 0);
   13.35 +void *ucx_map_get(UcxMap const *map, UcxKey key) {
   13.36 +    return ucx_map_get_and_remove((UcxMap *)map, key, 0);
   13.37  }
   13.38  
   13.39  void *ucx_map_remove(UcxMap *map, UcxKey key) {
   13.40 @@ -294,7 +299,7 @@
   13.41      return h;
   13.42  }
   13.43  
   13.44 -UcxMapIterator ucx_map_iterator(UcxMap *map) {
   13.45 +UcxMapIterator ucx_map_iterator(UcxMap const *map) {
   13.46      UcxMapIterator i;
   13.47      i.map = map;
   13.48      i.cur = NULL;
   13.49 @@ -335,3 +340,63 @@
   13.50      return 0;
   13.51  }
   13.52  
   13.53 +UcxMap* ucx_map_union(const UcxMap *first, const UcxMap *second,
   13.54 +                      copy_func cpfnc, void* cpdata) {
   13.55 +    return ucx_map_union_a(ucx_default_allocator(),
   13.56 +            first, second, cpfnc, cpdata);
   13.57 +}
   13.58 +
   13.59 +UcxMap* ucx_map_union_a(UcxAllocator *allocator,
   13.60 +                        const UcxMap *first, const UcxMap *second,
   13.61 +                        copy_func cpfnc, void* cpdata) {
   13.62 +    UcxMap* result = ucx_map_clone_a(allocator, first, cpfnc, cpdata);
   13.63 +    ucx_map_copy(second, result, cpfnc, cpdata);
   13.64 +    return result;
   13.65 +}
   13.66 +
   13.67 +UcxMap* ucx_map_intersection(const UcxMap *first, const UcxMap *second,
   13.68 +                             copy_func cpfnc, void* cpdata) {
   13.69 +    return ucx_map_intersection_a(ucx_default_allocator(),
   13.70 +            first, second, cpfnc, cpdata);
   13.71 +}
   13.72 +
   13.73 +UcxMap* ucx_map_intersection_a(UcxAllocator *allocator,
   13.74 +                               const UcxMap *first, const UcxMap *second,
   13.75 +                               copy_func cpfnc, void* cpdata) {
   13.76 +    UcxMap *result = ucx_map_new_a(allocator, first->size < second->size ?
   13.77 +            first->size : second->size);
   13.78 +
   13.79 +    UcxMapIterator iter = ucx_map_iterator(first);
   13.80 +    void* value;
   13.81 +    UCX_MAP_FOREACH(key, value, iter) {
   13.82 +        if (ucx_map_get(second, key)) {
   13.83 +            ucx_map_put(result, key, cpfnc ? cpfnc(value, cpdata) : value);
   13.84 +        }
   13.85 +    }
   13.86 +
   13.87 +    return result;
   13.88 +}
   13.89 +
   13.90 +UcxMap* ucx_map_difference(const UcxMap *first, const UcxMap *second,
   13.91 +                           copy_func cpfnc, void* cpdata) {
   13.92 +    return ucx_map_difference_a(ucx_default_allocator(),
   13.93 +            first, second, cpfnc, cpdata);
   13.94 +}
   13.95 +
   13.96 +UcxMap* ucx_map_difference_a(UcxAllocator *allocator,
   13.97 +                             const UcxMap *first, const UcxMap *second,
   13.98 +                             copy_func cpfnc, void* cpdata) {
   13.99 +
  13.100 +    UcxMap *result = ucx_map_new_a(allocator, first->size - second->count);
  13.101 +
  13.102 +    UcxMapIterator iter = ucx_map_iterator(first);
  13.103 +    void* value;
  13.104 +    UCX_MAP_FOREACH(key, value, iter) {
  13.105 +        if (!ucx_map_get(second, key)) {
  13.106 +            ucx_map_put(result, key, cpfnc ? cpfnc(value, cpdata) : value);
  13.107 +        }
  13.108 +    }
  13.109 +
  13.110 +    ucx_map_rehash(result);
  13.111 +    return result;
  13.112 +}
  13.113 \ No newline at end of file
    14.1 --- a/src/string.c	Mon Dec 30 09:52:07 2019 +0100
    14.2 +++ b/src/string.c	Mon Dec 30 09:52:44 2019 +0100
    14.3 @@ -36,6 +36,10 @@
    14.4  #include <stdint.h>
    14.5  #include <ctype.h>
    14.6  
    14.7 +#ifndef _WIN32
    14.8 +#include <strings.h> /* for strncasecmp() */
    14.9 +#endif /* _WIN32 */
   14.10 +
   14.11  sstr_t sstr(char *cstring) {
   14.12      sstr_t string;
   14.13      string.ptr = cstring;
   14.14 @@ -66,6 +70,8 @@
   14.15  
   14.16  
   14.17  size_t scstrnlen(size_t n, ...) {
   14.18 +    if (n == 0) return 0;
   14.19 +    
   14.20      va_list ap;
   14.21      va_start(ap, n);
   14.22      
   14.23 @@ -592,6 +598,38 @@
   14.24      }
   14.25  }
   14.26  
   14.27 +int scstrcaseprefix(scstr_t string, scstr_t prefix) {
   14.28 +    if (string.length == 0) {
   14.29 +        return prefix.length == 0;
   14.30 +    }
   14.31 +    if (prefix.length == 0) {
   14.32 +        return 1;
   14.33 +    }
   14.34 +    
   14.35 +    if (prefix.length > string.length) {
   14.36 +        return 0;
   14.37 +    } else {
   14.38 +        scstr_t subs = scstrsubsl(string, 0, prefix.length);
   14.39 +        return scstrcasecmp(subs, prefix) == 0;
   14.40 +    }
   14.41 +}
   14.42 +
   14.43 +int scstrcasesuffix(scstr_t string, scstr_t suffix) {
   14.44 +    if (string.length == 0) {
   14.45 +        return suffix.length == 0;
   14.46 +    }
   14.47 +    if (suffix.length == 0) {
   14.48 +        return 1;
   14.49 +    }
   14.50 +    
   14.51 +    if (suffix.length > string.length) {
   14.52 +        return 0;
   14.53 +    } else {
   14.54 +        scstr_t subs = scstrsubs(string, string.length-suffix.length);
   14.55 +        return scstrcasecmp(subs, suffix) == 0;
   14.56 +    }
   14.57 +}
   14.58 +
   14.59  sstr_t scstrlower(scstr_t string) {
   14.60      sstr_t ret = sstrdup(string);
   14.61      for (size_t i = 0; i < ret.length ; i++) {
   14.62 @@ -624,6 +662,136 @@
   14.63      return ret;
   14.64  }
   14.65  
   14.66 +#define REPLACE_INDEX_BUFFER_MAX 100
   14.67 +
   14.68 +struct scstrreplace_ibuf {
   14.69 +    size_t* buf;
   14.70 +    unsigned int len; /* small indices */
   14.71 +    struct scstrreplace_ibuf* next;
   14.72 +};
   14.73 +
   14.74 +static void scstrrepl_free_ibuf(struct scstrreplace_ibuf *buf) {
   14.75 +    while (buf) {
   14.76 +        struct scstrreplace_ibuf *next = buf->next;
   14.77 +        free(buf->buf);
   14.78 +        free(buf);
   14.79 +        buf = next;
   14.80 +    }
   14.81 +}
   14.82 +
   14.83 +sstr_t scstrreplacen_a(UcxAllocator *allocator, scstr_t str,
   14.84 +                     scstr_t pattern, scstr_t replacement, size_t replmax) {
   14.85 +
   14.86 +    if (pattern.length == 0 || pattern.length > str.length || replmax == 0)
   14.87 +        return sstrdup(str);
   14.88 +
   14.89 +    /* Compute expected buffer length */
   14.90 +    size_t ibufmax = str.length / pattern.length;
   14.91 +    size_t ibuflen = replmax < ibufmax ? replmax : ibufmax;
   14.92 +    if (ibuflen > REPLACE_INDEX_BUFFER_MAX) {
   14.93 +        ibuflen = REPLACE_INDEX_BUFFER_MAX;
   14.94 +    }
   14.95 +
   14.96 +    /* Allocate first index buffer */
   14.97 +    struct scstrreplace_ibuf *firstbuf, *curbuf;
   14.98 +    firstbuf = curbuf = calloc(1, sizeof(struct scstrreplace_ibuf));
   14.99 +    if (!firstbuf) return sstrn(NULL, 0);
  14.100 +    firstbuf->buf = calloc(ibuflen, sizeof(size_t));
  14.101 +    if (!firstbuf->buf) {
  14.102 +        free(firstbuf);
  14.103 +        return sstrn(NULL, 0);
  14.104 +    }
  14.105 +
  14.106 +    /* Search occurrences */
  14.107 +    scstr_t searchstr = str;
  14.108 +    size_t found = 0;
  14.109 +    do {
  14.110 +        scstr_t match = scstrscstr(searchstr, pattern);
  14.111 +        if (match.length > 0) {
  14.112 +            /* Allocate next buffer in chain, if required */
  14.113 +            if (curbuf->len == ibuflen) {
  14.114 +                struct scstrreplace_ibuf *nextbuf =
  14.115 +                        calloc(1, sizeof(struct scstrreplace_ibuf));
  14.116 +                if (!nextbuf) {
  14.117 +                    scstrrepl_free_ibuf(firstbuf);
  14.118 +                    return sstrn(NULL, 0);
  14.119 +                }
  14.120 +                nextbuf->buf = calloc(ibuflen, sizeof(size_t));
  14.121 +                if (!nextbuf->buf) {
  14.122 +                    free(nextbuf);
  14.123 +                    scstrrepl_free_ibuf(firstbuf);
  14.124 +                    return sstrn(NULL, 0);
  14.125 +                }
  14.126 +                curbuf->next = nextbuf;
  14.127 +                curbuf = nextbuf;
  14.128 +            }
  14.129 +
  14.130 +            /* Record match index */
  14.131 +            found++;
  14.132 +            size_t idx = match.ptr - str.ptr;
  14.133 +            curbuf->buf[curbuf->len++] = idx;
  14.134 +            searchstr.ptr = match.ptr + pattern.length;
  14.135 +            searchstr.length = str.length - idx - pattern.length;
  14.136 +        } else {
  14.137 +            break;
  14.138 +        }
  14.139 +    } while (searchstr.length > 0 && found < replmax);
  14.140 +
  14.141 +    /* Allocate result string */
  14.142 +    sstr_t result;
  14.143 +    {
  14.144 +        ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length;
  14.145 +        size_t rcount = 0;
  14.146 +        curbuf = firstbuf;
  14.147 +        do {
  14.148 +            rcount += curbuf->len;
  14.149 +            curbuf = curbuf->next;
  14.150 +        } while (curbuf);
  14.151 +        result.length = str.length + rcount * adjlen;
  14.152 +        result.ptr = almalloc(allocator, result.length);
  14.153 +        if (!result.ptr) {
  14.154 +            scstrrepl_free_ibuf(firstbuf);
  14.155 +            return sstrn(NULL, 0);
  14.156 +        }
  14.157 +    }
  14.158 +
  14.159 +    /* Build result string */
  14.160 +    curbuf = firstbuf;
  14.161 +    size_t srcidx = 0;
  14.162 +    char* destptr = result.ptr;
  14.163 +    do {
  14.164 +        for (size_t i = 0; i < curbuf->len; i++) {
  14.165 +            /* Copy source part up to next match*/
  14.166 +            size_t idx = curbuf->buf[i];
  14.167 +            size_t srclen = idx - srcidx;
  14.168 +            if (srclen > 0) {
  14.169 +                memcpy(destptr, str.ptr+srcidx, srclen);
  14.170 +                destptr += srclen;
  14.171 +                srcidx += srclen;
  14.172 +            }
  14.173 +
  14.174 +            /* Copy the replacement and skip the source pattern */
  14.175 +            srcidx += pattern.length;
  14.176 +            memcpy(destptr, replacement.ptr, replacement.length);
  14.177 +            destptr += replacement.length;
  14.178 +        }
  14.179 +        curbuf = curbuf->next;
  14.180 +    } while (curbuf);
  14.181 +    memcpy(destptr, str.ptr+srcidx, str.length-srcidx);
  14.182 +
  14.183 +    /* Free index buffer */
  14.184 +    scstrrepl_free_ibuf(firstbuf);
  14.185 +
  14.186 +    return result;
  14.187 +}
  14.188 +
  14.189 +sstr_t scstrreplacen(scstr_t str, scstr_t pattern,
  14.190 +        scstr_t replacement, size_t replmax) {
  14.191 +    return scstrreplacen_a(ucx_default_allocator(),
  14.192 +            str, pattern, replacement, replmax);
  14.193 +}
  14.194 +
  14.195 +
  14.196  // type adjustment functions
  14.197  scstr_t ucx_sc2sc(scstr_t str) {
  14.198      return str;
    15.1 --- a/src/ucx/array.h	Mon Dec 30 09:52:07 2019 +0100
    15.2 +++ b/src/ucx/array.h	Mon Dec 30 09:52:44 2019 +0100
    15.3 @@ -71,6 +71,7 @@
    15.4  
    15.5  /**
    15.6   * Sets an element in an arbitrary user defined array.
    15.7 + * The data is copied from the specified data location.
    15.8   * 
    15.9   * If the capacity is insufficient, the array is automatically reallocated and
   15.10   * the possibly new pointer is stored in the <code>array</code> argument.
   15.11 @@ -82,7 +83,7 @@
   15.12   * @param capacity a pointer to the capacity
   15.13   * @param elmsize the size of each element
   15.14   * @param idx the index of the element to set
   15.15 - * @param data the element data
   15.16 + * @param data a pointer to the element data
   15.17   * @return zero on success or non-zero on error (errno will be set)
   15.18   */
   15.19  #define ucx_array_util_set(array, capacity, elmsize, idx, data) \
   15.20 @@ -90,22 +91,8 @@
   15.21                           elmsize, idx, data)
   15.22  
   15.23  /**
   15.24 - * Convenience macro for ucx_array_util_set() which automatically computes
   15.25 - * <code>sizeof(data)</code>.
   15.26 - * 
   15.27 - * @param array a pointer to location of the array pointer
   15.28 - * @param capacity a pointer to the capacity
   15.29 - * @param idx the index of the element to set
   15.30 - * @param data the element data
   15.31 - * @return zero on success or non-zero on error (errno will be set)
   15.32 - * @see ucx_array_util_set()
   15.33 - */
   15.34 -#define UCX_ARRAY_UTIL_SET(array, capacity, idx, data) \
   15.35 -    ucx_array_util_set_a(ucx_default_allocator(), (void**)(array), capacity, \
   15.36 -                         sizeof(data), idx, data)
   15.37 -
   15.38 -/**
   15.39   * Sets an element in an arbitrary user defined array.
   15.40 + * The data is copied from the specified data location.
   15.41   * 
   15.42   * If the capacity is insufficient, the array is automatically reallocated
   15.43   * using the specified allocator and the possibly new pointer is stored in
   15.44 @@ -119,27 +106,53 @@
   15.45   * @param capacity a pointer to the capacity
   15.46   * @param elmsize the size of each element
   15.47   * @param idx the index of the element to set
   15.48 - * @param ... the element data
   15.49 + * @param data a pointer to the element data
   15.50   * @return zero on success or non-zero on error (errno will be set)
   15.51   */
   15.52  int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity,
   15.53 -    size_t elmsize, size_t idx, ...);
   15.54 -
   15.55 +    size_t elmsize, size_t idx, void* data);
   15.56  
   15.57  /**
   15.58 - * Convenience macro for ucx_array_util_set_a() which automatically computes
   15.59 - * <code>sizeof(data)</code>.
   15.60 + * Stores a pointer in an arbitrary user defined array.
   15.61 + * The element size of the array must be sizeof(void*).
   15.62 + * 
   15.63 + * If the capacity is insufficient, the array is automatically reallocated and
   15.64 + * the possibly new pointer is stored in the <code>array</code> argument.
   15.65 + * 
   15.66 + * On reallocation the capacity of the array is doubled until it is sufficient.
   15.67 + * The new capacity is stored back to <code>capacity</code>.
   15.68 + *  
   15.69 + * @param array a pointer to location of the array pointer
   15.70 + * @param capacity a pointer to the capacity
   15.71 + * @param idx the index of the element to set
   15.72 + * @param ptr the pointer to store
   15.73 + * @return zero on success or non-zero on error (errno will be set)
   15.74 + */
   15.75 +#define ucx_array_util_setptr(array, capacity, idx, ptr) \
   15.76 +    ucx_array_util_setptr_a(ucx_default_allocator(), (void**)(array), \
   15.77 +                            capacity, idx, ptr)
   15.78 +
   15.79 +/**
   15.80 + * Stores a pointer in an arbitrary user defined array.
   15.81 + * The element size of the array must be sizeof(void*).
   15.82 + * 
   15.83 + * If the capacity is insufficient, the array is automatically reallocated
   15.84 + * using the specified allocator and the possibly new pointer is stored in
   15.85 + * the <code>array</code> argument.
   15.86 + * 
   15.87 + * On reallocation the capacity of the array is doubled until it is sufficient.
   15.88 + * The new capacity is stored back to <code>capacity</code>. 
   15.89   * 
   15.90   * @param alloc the allocator that shall be used to reallocate the array
   15.91   * @param array a pointer to location of the array pointer
   15.92   * @param capacity a pointer to the capacity
   15.93   * @param idx the index of the element to set
   15.94 - * @param data the element data
   15.95 + * @param ptr the pointer to store
   15.96   * @return zero on success or non-zero on error (errno will be set)
   15.97 - * @see ucx_array_util_set_a()
   15.98   */
   15.99 -#define UCX_ARRAY_UTIL_SET_A(alloc, array, capacity, idx, data) \
  15.100 -    ucx_array_util_set_a(alloc, capacity, sizeof(data), idx, data)
  15.101 +int ucx_array_util_setptr_a(UcxAllocator* alloc, void** array, size_t* capacity,
  15.102 +    size_t idx, void* ptr);
  15.103 +
  15.104  
  15.105  /**
  15.106   * Creates a new UCX array with the given capacity and element size.
  15.107 @@ -174,6 +187,7 @@
  15.108   * Initializes a UCX array structure using the specified allocator.
  15.109   * The structure must be uninitialized as the data pointer will be overwritten.
  15.110   * 
  15.111 + * @param array the structure to initialize
  15.112   * @param capacity the initial capacity
  15.113   * @param elemsize the element size
  15.114   * @param allocator the allocator to use
  15.115 @@ -290,88 +304,6 @@
  15.116  int ucx_array_set_from(UcxArray *array, size_t index, void *data, size_t count);
  15.117  
  15.118  /**
  15.119 - * Inserts an element at the end of the array.
  15.120 - * 
  15.121 - * This is an O(1) operation.
  15.122 - * The array will automatically grow, if the capacity is exceeded.
  15.123 - * If the type of the argument has a different size than the element size of
  15.124 - * this array, the behavior is undefined.
  15.125 - * 
  15.126 - * @param array a pointer the array where to append the data
  15.127 - * @param elem the value to insert
  15.128 - * @return zero on success, non-zero if a reallocation was necessary but failed
  15.129 - * @see ucx_array_append_from()
  15.130 - * @see ucx_array_set()
  15.131 - */
  15.132 -#define ucx_array_append(array, elem) ucx_array_appendv(array, elem)
  15.133 -
  15.134 -/**
  15.135 - * For internal use.
  15.136 - * Use ucx_array_append()
  15.137 - * 
  15.138 - * @param array
  15.139 - * @param ... 
  15.140 - * @return 
  15.141 - * @see ucx_array_append()
  15.142 - */
  15.143 -int ucx_array_appendv(UcxArray *array, ...);
  15.144 -
  15.145 -
  15.146 -/**
  15.147 - * Inserts an element at the beginning of the array.
  15.148 - * 
  15.149 - * This is an expensive operation, because the contents must be moved.
  15.150 - * If there is no particular reason to prepend data, you should use
  15.151 - * ucx_array_append() instead.
  15.152 - * 
  15.153 - * @param array a pointer the array where to prepend the data
  15.154 - * @param elem the value to insert
  15.155 - * @return zero on success, non-zero if a reallocation was necessary but failed
  15.156 - * @see ucx_array_append()
  15.157 - * @see ucx_array_set_from()
  15.158 - * @see ucx_array_prepend_from()
  15.159 - */
  15.160 -#define ucx_array_prepend(array, elem) ucx_array_prependv(array, elem)
  15.161 -
  15.162 -/**
  15.163 - * For internal use.
  15.164 - * Use ucx_array_prepend()
  15.165 - * 
  15.166 - * @param array
  15.167 - * @param ... 
  15.168 - * @return 
  15.169 - * @see ucx_array_prepend()
  15.170 - */
  15.171 -int ucx_array_prependv(UcxArray *array, ...);
  15.172 -
  15.173 -
  15.174 -/**
  15.175 - * Sets an element at the specified index.
  15.176 - * 
  15.177 - * If the any index is out of bounds, the array automatically grows.
  15.178 - * 
  15.179 - * @param array a pointer the array where to set the data
  15.180 - * @param index the index of the element to set
  15.181 - * @param elem the value to set
  15.182 - * @return zero on success, non-zero if a reallocation was necessary but failed
  15.183 - * @see ucx_array_append()
  15.184 - * @see ucx_array_set_from()
  15.185 - */
  15.186 -#define ucx_array_set(array, index, elem) ucx_array_setv(array, index, elem)
  15.187 -
  15.188 -/**
  15.189 - * For internal use.
  15.190 - * Use ucx_array_set()
  15.191 - * 
  15.192 - * @param array
  15.193 - * @param index
  15.194 - * @param ... 
  15.195 - * @return 
  15.196 - * @see ucx_array_set()
  15.197 - */
  15.198 -int ucx_array_setv(UcxArray *array, size_t index, ...);
  15.199 -
  15.200 -/**
  15.201   * Concatenates two arrays.
  15.202   * 
  15.203   * The contents of the second array are appended to the first array in one
  15.204 @@ -506,6 +438,18 @@
  15.205   */
  15.206  int ucx_array_reserve(UcxArray* array, size_t capacity);
  15.207  
  15.208 +/**
  15.209 + * Resizes the capacity, if the specified number of elements would not fit.
  15.210 + * 
  15.211 + * A call to ucx_array_grow(array, count) is effectively the same as
  15.212 + * ucx_array_reserve(array, array->size+count).
  15.213 + * 
  15.214 + * @param array a pointer to the array
  15.215 + * @param count the number of elements that should additionally fit
  15.216 + * into the array
  15.217 + * @return zero on success, non-zero if reallocation failed
  15.218 + */
  15.219 +int ucx_array_grow(UcxArray* array, size_t count);
  15.220  
  15.221  
  15.222  #ifdef	__cplusplus
    16.1 --- a/src/ucx/list.h	Mon Dec 30 09:52:07 2019 +0100
    16.2 +++ b/src/ucx/list.h	Mon Dec 30 09:52:44 2019 +0100
    16.3 @@ -57,7 +57,7 @@
    16.4   * @param elem The variable name of the element
    16.5   */
    16.6  #define UCX_FOREACH(elem,list) \
    16.7 -        for (UcxList* elem = list ; elem != NULL ; elem = elem->next)
    16.8 +        for (UcxList* elem = (UcxList*) list ; elem != NULL ; elem = elem->next)
    16.9  
   16.10  /**
   16.11   * UCX list type.
   16.12 @@ -99,7 +99,7 @@
   16.13   * @param data additional data for the copy_func()
   16.14   * @return a pointer to the copy
   16.15   */
   16.16 -UcxList *ucx_list_clone(UcxList *list, copy_func cpyfnc, void* data);
   16.17 +UcxList *ucx_list_clone(const UcxList *list, copy_func cpyfnc, void* data);
   16.18  
   16.19  /**
   16.20   * Creates an element-wise copy of a list using a UcxAllocator.
   16.21 @@ -117,7 +117,7 @@
   16.22   * @return a pointer to the copy
   16.23   * @see ucx_list_clone()
   16.24   */
   16.25 -UcxList *ucx_list_clone_a(UcxAllocator *allocator, UcxList *list,
   16.26 +UcxList *ucx_list_clone_a(UcxAllocator *allocator, const UcxList *list,
   16.27          copy_func cpyfnc, void* data);
   16.28  
   16.29  /**
   16.30 @@ -328,7 +328,8 @@
   16.31   * @return the index of the element containing the specified data or -1 if the
   16.32   * data is not found in this list
   16.33   */
   16.34 -ssize_t ucx_list_find(UcxList *list, void *elem, cmp_func cmpfnc, void *data);
   16.35 +ssize_t ucx_list_find(const UcxList *list, void *elem,
   16.36 +    cmp_func cmpfnc, void *data);
   16.37  
   16.38  /**
   16.39   * Checks, if a list contains a specific element.
   16.40 @@ -342,7 +343,8 @@
   16.41   * @return 1, if and only if the list contains the specified element data
   16.42   * @see ucx_list_find()
   16.43   */
   16.44 -int ucx_list_contains(UcxList *list, void *elem, cmp_func cmpfnc, void *data);
   16.45 +int ucx_list_contains(const UcxList *list, void *elem,
   16.46 +    cmp_func cmpfnc, void *data);
   16.47  
   16.48  /**
   16.49   * Sorts a UcxList with natural merge sort.
   16.50 @@ -388,6 +390,120 @@
   16.51  UcxList *ucx_list_remove_a(UcxAllocator *allocator, UcxList *list,
   16.52          UcxList *element);
   16.53  
   16.54 +/**
   16.55 + * Returns the union of two lists.
   16.56 + * 
   16.57 + * The union is a list of unique elements regarding cmpfnc obtained from
   16.58 + * both source lists.
   16.59 + * 
   16.60 + * @param left the left source list
   16.61 + * @param right the right source list
   16.62 + * @param cmpfnc a function to compare elements
   16.63 + * @param cmpdata additional data for the compare function
   16.64 + * @param cpfnc a function to copy the elements
   16.65 + * @param cpdata additional data for the copy function
   16.66 + * @return a new list containing the union
   16.67 + */
   16.68 +UcxList* ucx_list_union(const UcxList *left, const UcxList *right,
   16.69 +    cmp_func cmpfnc, void* cmpdata,
   16.70 +    copy_func cpfnc, void* cpdata);
   16.71 +
   16.72 +/**
   16.73 + * Returns the union of two lists.
   16.74 + * 
   16.75 + * The union is a list of unique elements regarding cmpfnc obtained from
   16.76 + * both source lists.
   16.77 + * 
   16.78 + * @param allocator allocates the new list elements
   16.79 + * @param left the left source list
   16.80 + * @param right the right source list
   16.81 + * @param cmpfnc a function to compare elements
   16.82 + * @param cmpdata additional data for the compare function
   16.83 + * @param cpfnc a function to copy the elements
   16.84 + * @param cpdata additional data for the copy function
   16.85 + * @return a new list containing the union
   16.86 + */
   16.87 +UcxList* ucx_list_union_a(UcxAllocator *allocator,
   16.88 +    const UcxList *left, const UcxList *right,
   16.89 +    cmp_func cmpfnc, void* cmpdata,
   16.90 +    copy_func cpfnc, void* cpdata);
   16.91 +
   16.92 +/**
   16.93 + * Returns the intersection of two lists.
   16.94 + * 
   16.95 + * The intersection contains all elements of the left list
   16.96 + * (including duplicates) that can be found in the right list.
   16.97 + * 
   16.98 + * @param left the left source list
   16.99 + * @param right the right source list
  16.100 + * @param cmpfnc a function to compare elements
  16.101 + * @param cmpdata additional data for the compare function
  16.102 + * @param cpfnc a function to copy the elements
  16.103 + * @param cpdata additional data for the copy function
  16.104 + * @return a new list containing the intersection
  16.105 + */
  16.106 +UcxList* ucx_list_intersection(const UcxList *left, const UcxList *right,
  16.107 +    cmp_func cmpfnc, void* cmpdata,
  16.108 +    copy_func cpfnc, void* cpdata);
  16.109 +
  16.110 +/**
  16.111 + * Returns the intersection of two lists.
  16.112 + * 
  16.113 + * The intersection contains all elements of the left list
  16.114 + * (including duplicates) that can be found in the right list.
  16.115 + * 
  16.116 + * @param allocator allocates the new list elements
  16.117 + * @param left the left source list
  16.118 + * @param right the right source list
  16.119 + * @param cmpfnc a function to compare elements
  16.120 + * @param cmpdata additional data for the compare function
  16.121 + * @param cpfnc a function to copy the elements
  16.122 + * @param cpdata additional data for the copy function
  16.123 + * @return a new list containing the intersection
  16.124 + */
  16.125 +UcxList* ucx_list_intersection_a(UcxAllocator *allocator,
  16.126 +    const UcxList *left, const UcxList *right,
  16.127 +    cmp_func cmpfnc, void* cmpdata,
  16.128 +    copy_func cpfnc, void* cpdata);
  16.129 +
  16.130 +/**
  16.131 + * Returns the difference of two lists.
  16.132 + * 
  16.133 + * The difference contains all elements of the left list
  16.134 + * (including duplicates) that are not equal to any element of the right list.
  16.135 + * 
  16.136 + * @param left the left source list
  16.137 + * @param right the right source list
  16.138 + * @param cmpfnc a function to compare elements
  16.139 + * @param cmpdata additional data for the compare function
  16.140 + * @param cpfnc a function to copy the elements
  16.141 + * @param cpdata additional data for the copy function
  16.142 + * @return a new list containing the difference
  16.143 + */
  16.144 +UcxList* ucx_list_difference(const UcxList *left, const UcxList *right,
  16.145 +    cmp_func cmpfnc, void* cmpdata,
  16.146 +    copy_func cpfnc, void* cpdata);
  16.147 +
  16.148 +/**
  16.149 + * Returns the difference of two lists.
  16.150 + * 
  16.151 + * The difference contains all elements of the left list
  16.152 + * (including duplicates) that are not equal to any element of the right list.
  16.153 + * 
  16.154 + * @param allocator allocates the new list elements
  16.155 + * @param left the left source list
  16.156 + * @param right the right source list
  16.157 + * @param cmpfnc a function to compare elements
  16.158 + * @param cmpdata additional data for the compare function
  16.159 + * @param cpfnc a function to copy the elements
  16.160 + * @param cpdata additional data for the copy function
  16.161 + * @return a new list containing the difference
  16.162 + */
  16.163 +UcxList* ucx_list_difference_a(UcxAllocator *allocator,
  16.164 +    const UcxList *left, const UcxList *right,
  16.165 +    cmp_func cmpfnc, void* cmpdata,
  16.166 +    copy_func cpfnc, void* cpdata);
  16.167 +
  16.168  #ifdef	__cplusplus
  16.169  }
  16.170  #endif
    17.1 --- a/src/ucx/logging.h	Mon Dec 30 09:52:07 2019 +0100
    17.2 +++ b/src/ucx/logging.h	Mon Dec 30 09:52:44 2019 +0100
    17.3 @@ -160,7 +160,10 @@
    17.4   * format is:
    17.5   * 
    17.6   * <code>[LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message</code>
    17.7 - * 
    17.8 + *
    17.9 + * The source file name is reduced to the actual file name. This is necessary to
   17.10 + * get consistent behavior over different definitions of the __FILE__ macro.
   17.11 + *
   17.12   * <b>Attention:</b> the message (including automatically generated information)
   17.13   * is limited to 4096 characters. The level description is limited to
   17.14   * 256 characters and the timestamp string is limited to 128 characters.
    18.1 --- a/src/ucx/map.h	Mon Dec 30 09:52:07 2019 +0100
    18.2 +++ b/src/ucx/map.h	Mon Dec 30 09:52:44 2019 +0100
    18.3 @@ -124,7 +124,7 @@
    18.4  /** Structure for an iterator over a UcxMap. */
    18.5  struct UcxMapIterator {
    18.6      /** The map to iterate over. */
    18.7 -    UcxMap        *map;
    18.8 +    UcxMap const  *map;
    18.9      
   18.10      /** The current map element. */
   18.11      UcxMapElement *cur;
   18.12 @@ -211,7 +211,7 @@
   18.13   * @param data additional data for the copy function
   18.14   * @return 0 on success or a non-zero value on memory allocation errors
   18.15   */
   18.16 -int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data);
   18.17 +int ucx_map_copy(UcxMap const *from, UcxMap *to, copy_func fnc, void *data);
   18.18  
   18.19  /**
   18.20   * Clones the map and rehashes if necessary.
   18.21 @@ -227,7 +227,25 @@
   18.22   * @return the cloned map
   18.23   * @see ucx_map_copy()
   18.24   */
   18.25 -UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
   18.26 +UcxMap *ucx_map_clone(UcxMap const *map, copy_func fnc, void *data);
   18.27 +
   18.28 +/**
   18.29 + * Clones the map and rehashes if necessary.
   18.30 + *
   18.31 + * <b>Note:</b> In contrast to ucx_map_rehash() the load factor is irrelevant.
   18.32 + * This function <i>always</i> ensures a new UcxMap.size of at least
   18.33 + * 2.5*UcxMap.count.
   18.34 + *
   18.35 + * @param allocator the allocator to use for the cloned map
   18.36 + * @param map the map to clone
   18.37 + * @param fnc the copy function to use or <code>NULL</code> if the new and
   18.38 + * the old map shall share the data pointers
   18.39 + * @param data additional data for the copy function
   18.40 + * @return the cloned map
   18.41 + * @see ucx_map_copy()
   18.42 + */
   18.43 +UcxMap *ucx_map_clone_a(UcxAllocator *allocator,
   18.44 +                        UcxMap const *map, copy_func fnc, void *data);
   18.45  
   18.46  /**
   18.47   * Increases size of the hash map, if necessary.
   18.48 @@ -264,7 +282,7 @@
   18.49   * @param key the key
   18.50   * @return the value
   18.51   */
   18.52 -void* ucx_map_get(UcxMap *map, UcxKey key);
   18.53 +void* ucx_map_get(UcxMap const *map, UcxKey key);
   18.54  
   18.55  /**
   18.56   * Removes a key/value-pair from the map by using the key.
   18.57 @@ -406,7 +424,7 @@
   18.58   * first element list
   18.59   * @see ucx_map_iter_next()
   18.60   */
   18.61 -UcxMapIterator ucx_map_iterator(UcxMap *map);
   18.62 +UcxMapIterator ucx_map_iterator(UcxMap const *map);
   18.63  
   18.64  /**
   18.65   * Proceeds to the next element of the map (if any).
   18.66 @@ -426,6 +444,102 @@
   18.67   */
   18.68  int ucx_map_iter_next(UcxMapIterator *iterator, UcxKey *key, void **value);
   18.69  
   18.70 +/**
   18.71 + * Returns the union of two maps.
   18.72 + *
   18.73 + * The union is a fresh map which is filled by two successive calls of
   18.74 + * ucx_map_copy() on the two input maps.
   18.75 + *
   18.76 + * @param first the first source map
   18.77 + * @param second the second source map
   18.78 + * @param cpfnc a function to copy the elements
   18.79 + * @param cpdata additional data for the copy function
   18.80 + * @return a new map containing the union
   18.81 + */
   18.82 +UcxMap* ucx_map_union(const UcxMap *first, const UcxMap *second,
   18.83 +                      copy_func cpfnc, void* cpdata);
   18.84 +
   18.85 +/**
   18.86 + * Returns the union of two maps.
   18.87 + *
   18.88 + * The union is a fresh map which is filled by two successive calls of
   18.89 + * ucx_map_copy() on the two input maps.
   18.90 + *
   18.91 + * @param allocator the allocator that shall be used by the new map
   18.92 + * @param first the first source map
   18.93 + * @param second the second source map
   18.94 + * @param cpfnc a function to copy the elements
   18.95 + * @param cpdata additional data for the copy function
   18.96 + * @return a new map containing the union
   18.97 + */
   18.98 +UcxMap* ucx_map_union_a(UcxAllocator *allocator,
   18.99 +                        const UcxMap *first, const UcxMap *second,
  18.100 +                        copy_func cpfnc, void* cpdata);
  18.101 +
  18.102 +/**
  18.103 + * Returns the intersection of two maps.
  18.104 + *
  18.105 + * The intersection is defined as a copy of the first map with every element
  18.106 + * removed that has no valid key in the second map.
  18.107 + *
  18.108 + * @param first the first source map
  18.109 + * @param second the second source map
  18.110 + * @param cpfnc a function to copy the elements
  18.111 + * @param cpdata additional data for the copy function
  18.112 + * @return a new map containing the intersection
  18.113 + */
  18.114 +UcxMap* ucx_map_intersection(const UcxMap *first, const UcxMap *second,
  18.115 +                             copy_func cpfnc, void* cpdata);
  18.116 +
  18.117 +/**
  18.118 + * Returns the intersection of two maps.
  18.119 + *
  18.120 + * The intersection is defined as a copy of the first map with every element
  18.121 + * removed that has no valid key in the second map.
  18.122 + *
  18.123 + * @param allocator the allocator that shall be used by the new map
  18.124 + * @param first the first source map
  18.125 + * @param second the second source map
  18.126 + * @param cpfnc a function to copy the elements
  18.127 + * @param cpdata additional data for the copy function
  18.128 + * @return a new map containing the intersection
  18.129 + */
  18.130 +UcxMap* ucx_map_intersection_a(UcxAllocator *allocator,
  18.131 +                               const UcxMap *first, const UcxMap *second,
  18.132 +                               copy_func cpfnc, void* cpdata);
  18.133 +
  18.134 +/**
  18.135 + * Returns the difference of two maps.
  18.136 + *
  18.137 + * The difference contains a copy of all elements of the first map
  18.138 + * for which the corresponding keys cannot be found in the second map.
  18.139 + *
  18.140 + * @param first the first source map
  18.141 + * @param second the second source map
  18.142 + * @param cpfnc a function to copy the elements
  18.143 + * @param cpdata additional data for the copy function
  18.144 + * @return a new list containing the difference
  18.145 + */
  18.146 +UcxMap* ucx_map_difference(const UcxMap *first, const UcxMap *second,
  18.147 +                           copy_func cpfnc, void* cpdata);
  18.148 +
  18.149 +/**
  18.150 + * Returns the difference of two maps.
  18.151 + *
  18.152 + * The difference contains a copy of all elements of the first map
  18.153 + * for which the corresponding keys cannot be found in the second map.
  18.154 + *
  18.155 + * @param allocator the allocator that shall be used by the new map
  18.156 + * @param first the first source map
  18.157 + * @param second the second source map
  18.158 + * @param cpfnc a function to copy the elements
  18.159 + * @param cpdata additional data for the copy function
  18.160 + * @return a new list containing the difference
  18.161 + */
  18.162 +UcxMap* ucx_map_difference_a(UcxAllocator *allocator,
  18.163 +                             const UcxMap *first, const UcxMap *second,
  18.164 +                             copy_func cpfnc, void* cpdata);
  18.165 +
  18.166  
  18.167  #ifdef	__cplusplus
  18.168  }
    19.1 --- a/src/ucx/string.h	Mon Dec 30 09:52:07 2019 +0100
    19.2 +++ b/src/ucx/string.h	Mon Dec 30 09:52:44 2019 +0100
    19.3 @@ -83,6 +83,7 @@
    19.4  #ifdef	__cplusplus
    19.5  extern "C" {
    19.6  #endif
    19.7 +  
    19.8  /**
    19.9   * The UCX string structure.
   19.10   */
   19.11 @@ -112,7 +113,7 @@
   19.12  
   19.13  #ifdef __cplusplus
   19.14  /**
   19.15 - * One of two type adjustment functions that return a scstr_t.
   19.16 + * One of two type adjustment functions that return an scstr_t.
   19.17   * 
   19.18   * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
   19.19   * 
   19.20 @@ -129,7 +130,7 @@
   19.21  }
   19.22  
   19.23  /**
   19.24 - * One of two type adjustment functions that return a scstr_t.
   19.25 + * One of two type adjustment functions that return an scstr_t.
   19.26   * 
   19.27   * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
   19.28   * This variant is used, when the string is already immutable and no operation
   19.29 @@ -147,13 +148,13 @@
   19.30  /**
   19.31   * Converts a UCX string to an immutable UCX string (scstr_t).
   19.32   * @param str some UCX string
   19.33 - * @return the an immutable version of the provided string
   19.34 + * @return an immutable version of the provided string
   19.35   */
   19.36  #define SCSTR(s) s2scstr(s)
   19.37  #else
   19.38  
   19.39  /**
   19.40 - * One of two type adjustment functions that return a scstr_t.
   19.41 + * One of two type adjustment functions that return an scstr_t.
   19.42   * 
   19.43   * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
   19.44   * This variant is used, when the string is already immutable and no operation
   19.45 @@ -167,7 +168,7 @@
   19.46  scstr_t ucx_sc2sc(scstr_t str);
   19.47  
   19.48  /**
   19.49 - * One of two type adjustment functions that return a scstr_t.
   19.50 + * One of two type adjustment functions that return an scstr_t.
   19.51   * 
   19.52   * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
   19.53   * 
   19.54 @@ -182,7 +183,7 @@
   19.55  /**
   19.56   * Converts a UCX string to an immutable UCX string (scstr_t).
   19.57   * @param str some UCX string
   19.58 - * @return the an immutable version of the provided string
   19.59 + * @return an immutable version of the provided string
   19.60   */
   19.61  #define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str)
   19.62  
   19.63 @@ -191,7 +192,7 @@
   19.64  /**
   19.65   * Converts a UCX string to an immutable UCX string (scstr_t).
   19.66   * @param str some UCX string
   19.67 - * @return the an immutable version of the provided string
   19.68 + * @return an immutable version of the provided string
   19.69   */
   19.70  #define SCSTR(str) __builtin_choose_expr( \
   19.71          __builtin_types_compatible_p(typeof(str), sstr_t), \
   19.72 @@ -244,8 +245,8 @@
   19.73   * 
   19.74   * The length is implicitly inferred by using a call to <code>strlen()</code>.
   19.75   *
   19.76 - * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you
   19.77 - * do want a copy, use sstrdup() on the return value of this function.
   19.78 + * <b>Note:</b> the sstr_t will share the specified pointer to the C string.
   19.79 + * If you do want a copy, use sstrdup() on the return value of this function.
   19.80   * 
   19.81   * If you need to wrap a constant string, use scstr().
   19.82   * 
   19.83 @@ -259,8 +260,8 @@
   19.84  /**
   19.85   * Creates a new sstr_t of the specified length based on a C string.
   19.86   *
   19.87 - * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you
   19.88 - * do want a copy, use sstrdup() on the return value of this function.
   19.89 + * <b>Note:</b> the sstr_t will share the specified pointer to the C string.
   19.90 + * If you do want a copy, use sstrdup() on the return value of this function.
   19.91   * 
   19.92   * If you need to wrap a constant string, use scstrn().
   19.93   * 
   19.94 @@ -278,8 +279,8 @@
   19.95   * 
   19.96   * The length is implicitly inferred by using a call to <code>strlen()</code>.
   19.97   *
   19.98 - * <b>Note:</b> the scstr_t will hold a <i>reference</i> to the C string. If you
   19.99 - * do want a copy, use scstrdup() on the return value of this function.
  19.100 + * <b>Note:</b> the scstr_t will share the specified pointer to the C string.
  19.101 + * If you do want a copy, use scstrdup() on the return value of this function.
  19.102   * 
  19.103   * @param cstring the C string to wrap
  19.104   * @return a new scstr_t containing the C string
  19.105 @@ -292,9 +293,8 @@
  19.106  /**
  19.107   * Creates a new scstr_t of the specified length based on a constant C string.
  19.108   *
  19.109 - * <b>Note:</b> the scstr_t will hold a <i>reference</i> to the C string. If you
  19.110 - * do want a copy, use scstrdup() on the return value of this function.
  19.111 - * 
  19.112 + * <b>Note:</b> the scstr_t will share the specified pointer to the C string.
  19.113 + * If you do want a copy, use scstrdup() on the return value of this function. * 
  19.114   * 
  19.115   * @param cstring  the C string to wrap
  19.116   * @param length   the length of the string
  19.117 @@ -305,21 +305,24 @@
  19.118  scstr_t scstrn(const char *cstring, size_t length);
  19.119  
  19.120  /**
  19.121 - * Returns the cumulated length of all specified strings.
  19.122 + * Returns the accumulated length of all specified strings.
  19.123   * 
  19.124 - * <b>Attention:</b> if the count argument does not match the count of the
  19.125 + * <b>Attention:</b> if the count argument is larger than the count of the
  19.126   * specified strings, the behavior is undefined.
  19.127   *
  19.128 - * @param count    the total number of specified strings (so at least 1)
  19.129 + * @param count    the total number of specified strings
  19.130   * @param ...      all strings
  19.131 - * @return the cumulated length of all strings
  19.132 + * @return the accumulated length of all strings
  19.133   */
  19.134  size_t scstrnlen(size_t count, ...);
  19.135  
  19.136  /**
  19.137 - * Alias for scstrnlen() which automatically converts the arguments.
  19.138 + * Returns the accumulated length of all specified strings.
  19.139   * 
  19.140 - * @param count    the total number of specified strings (so at least 1)
  19.141 + * <b>Attention:</b> if the count argument is larger than the count of the
  19.142 + * specified strings, the behavior is undefined.
  19.143 + * 
  19.144 + * @param count    the total number of specified strings
  19.145   * @param ...      all strings
  19.146   * @return the cumulated length of all strings
  19.147   */
  19.148 @@ -342,7 +345,13 @@
  19.149  sstr_t scstrcat(size_t count, scstr_t s1, ...);
  19.150  
  19.151  /**
  19.152 - * Alias for scstrcat() which automatically converts the arguments.
  19.153 + * Concatenates two or more strings.
  19.154 + * 
  19.155 + * The resulting string will be allocated by standard <code>malloc()</code>. 
  19.156 + * So developers <b>MUST</b> pass the sstr_t.ptr to <code>free()</code>.
  19.157 + * 
  19.158 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
  19.159 + * terminated.
  19.160   * 
  19.161   * @param count   the total number of strings to concatenate
  19.162   * @param s1      first string
  19.163 @@ -354,35 +363,47 @@
  19.164  /**
  19.165   * Concatenates two or more strings using a UcxAllocator.
  19.166   * 
  19.167 - * See scstrcat() for details.
  19.168 + * The resulting string must be freed by the allocators <code>free()</code>
  19.169 + * implementation.
  19.170 + * 
  19.171 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
  19.172 + * terminated.
  19.173   *
  19.174 - * @param a       the allocator to use
  19.175 + * @param alloc   the allocator to use
  19.176   * @param count   the total number of strings to concatenate
  19.177   * @param s1      first string
  19.178   * @param ...     all remaining strings
  19.179   * @return the concatenated string
  19.180 + * 
  19.181 + * @see scstrcat()
  19.182   */
  19.183 -sstr_t scstrcat_a(UcxAllocator *a, size_t count, scstr_t s1, ...);
  19.184 +sstr_t scstrcat_a(UcxAllocator *alloc, size_t count, scstr_t s1, ...);
  19.185  
  19.186  /**
  19.187 - * Alias for scstrcat_a() which automatically converts the arguments.
  19.188 + * Concatenates two or more strings using a UcxAllocator.
  19.189   * 
  19.190 - * See sstrcat() for details.
  19.191 + * The resulting string must be freed by the allocators <code>free()</code>
  19.192 + * implementation.
  19.193 + * 
  19.194 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
  19.195 + * terminated.
  19.196   *
  19.197 - * @param a       the allocator to use
  19.198 + * @param alloc   the allocator to use
  19.199   * @param count   the total number of strings to concatenate
  19.200   * @param s1      first string
  19.201   * @param ...     all remaining strings
  19.202   * @return the concatenated string
  19.203 + * 
  19.204 + * @see sstrcat()
  19.205   */
  19.206 -#define sstrcat_a(a, count, s1, ...) \
  19.207 -    scstrcat_a(a, count, SCSTR(s1), __VA_ARGS__)
  19.208 +#define sstrcat_a(alloc, count, s1, ...) \
  19.209 +    scstrcat_a(alloc, count, SCSTR(s1), __VA_ARGS__)
  19.210  
  19.211  /**
  19.212   * Returns a substring starting at the specified location.
  19.213   * 
  19.214   * <b>Attention:</b> the new string references the same memory area as the
  19.215 - * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
  19.216 + * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
  19.217   * Use sstrdup() to get a copy.
  19.218   * 
  19.219   * @param string input string
  19.220 @@ -395,10 +416,10 @@
  19.221  sstr_t sstrsubs(sstr_t string, size_t start);
  19.222  
  19.223  /**
  19.224 - * Returns a substring with a maximum length starting at the specified location.
  19.225 + * Returns a substring with the given length starting at the specified location.
  19.226   * 
  19.227   * <b>Attention:</b> the new string references the same memory area as the
  19.228 - * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
  19.229 + * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
  19.230   * Use sstrdup() to get a copy.
  19.231   * 
  19.232   * @param string input string
  19.233 @@ -417,7 +438,7 @@
  19.234   * location.
  19.235   * 
  19.236   * <b>Attention:</b> the new string references the same memory area as the
  19.237 - * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
  19.238 +* input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
  19.239   * Use scstrdup() to get a copy.
  19.240   * 
  19.241   * @param string input string
  19.242 @@ -434,7 +455,7 @@
  19.243   * at the specified location.
  19.244   * 
  19.245   * <b>Attention:</b> the new string references the same memory area as the
  19.246 - * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
  19.247 + * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
  19.248   * Use scstrdup() to get a copy.
  19.249   * 
  19.250   * @param string input string
  19.251 @@ -522,7 +543,13 @@
  19.252  sstr_t scstrsstr(sstr_t string, scstr_t match);
  19.253  
  19.254  /**
  19.255 - * Alias for scstrsstr() which automatically converts the match string.
  19.256 + * Returns a substring starting at the location of the first occurrence of the
  19.257 + * specified string.
  19.258 + * 
  19.259 + * If the string does not contain the other string, an empty string is returned.
  19.260 + * 
  19.261 + * If <code>match</code> is an empty string, the complete <code>string</code> is
  19.262 + * returned.
  19.263   * 
  19.264   * @param string the string to be scanned
  19.265   * @param match  string containing the sequence of characters to match
  19.266 @@ -550,7 +577,13 @@
  19.267  scstr_t scstrscstr(scstr_t string, scstr_t match);
  19.268  
  19.269  /**
  19.270 - * Alias for scstrscstr() which automatically converts the match string.
  19.271 + * Returns an immutable substring starting at the location of the
  19.272 + * first occurrence of the specified immutable string.
  19.273 + * 
  19.274 + * If the string does not contain the other string, an empty string is returned.
  19.275 + * 
  19.276 + * If <code>match</code> is an empty string, the complete <code>string</code> is
  19.277 + * returned.
  19.278   * 
  19.279   * @param string the string to be scanned
  19.280   * @param match  string containing the sequence of characters to match
  19.281 @@ -595,6 +628,55 @@
  19.282   * delimiter.
  19.283   * 
  19.284   * <b>Attention:</b> The array pointer <b>AND</b> all sstr_t.ptr of the array
  19.285 + * items must be manually passed to <code>free()</code>. Use scstrsplit_a() with
  19.286 + * an allocator to managed memory, to avoid this.
  19.287 + *
  19.288 + * @param string the string to split
  19.289 + * @param delim  the delimiter string
  19.290 + * @param count  IN: the maximum size of the resulting array (0 = no limit),
  19.291 + *               OUT: the actual size of the array
  19.292 + * @return a sstr_t array containing the split strings or
  19.293 + * <code>NULL</code> on error
  19.294 + * 
  19.295 + * @see scstrsplit_a()
  19.296 + */
  19.297 +sstr_t* scstrsplit(scstr_t string, scstr_t delim, ssize_t *count);
  19.298 +
  19.299 +/**
  19.300 + * Splits a string into parts by using a delimiter string.
  19.301 + * 
  19.302 + * This function will return <code>NULL</code>, if one of the following happens:
  19.303 + * <ul>
  19.304 + *   <li>the string length is zero</li>
  19.305 + *   <li>the delimeter length is zero</li>
  19.306 + *   <li>the string equals the delimeter</li>
  19.307 + *   <li>memory allocation fails</li>
  19.308 + * </ul>
  19.309 + * 
  19.310 + * The integer referenced by <code>count</code> is used as input and determines
  19.311 + * the maximum size of the resulting array, i.e. the maximum count of splits to
  19.312 + * perform + 1.
  19.313 + * 
  19.314 + * The integer referenced by <code>count</code> is also used as output and is
  19.315 + * set to
  19.316 + * <ul>
  19.317 + *   <li>-2, on memory allocation errors</li>
  19.318 + *   <li>-1, if either the string or the delimiter is an empty string</li>
  19.319 + *   <li>0, if the string equals the delimiter</li>
  19.320 + *   <li>1, if the string does not contain the delimiter</li>
  19.321 + *   <li>the count of array items, otherwise</li>
  19.322 + * </ul>
  19.323 + * 
  19.324 + * If the string starts with the delimiter, the first item of the resulting
  19.325 + * array will be an empty string.
  19.326 + * 
  19.327 + * If the string ends with the delimiter and the maximum list size is not
  19.328 + * exceeded, the last array item will be an empty string.
  19.329 + * In case the list size would be exceeded, the last array item will be the
  19.330 + * remaining string after the last split, <i>including</i> the terminating
  19.331 + * delimiter.
  19.332 + * 
  19.333 + * <b>Attention:</b> The array pointer <b>AND</b> all sstr_t.ptr of the array
  19.334   * items must be manually passed to <code>free()</code>. Use sstrsplit_a() with
  19.335   * an allocator to managed memory, to avoid this.
  19.336   *
  19.337 @@ -605,20 +687,6 @@
  19.338   * @return a sstr_t array containing the split strings or
  19.339   * <code>NULL</code> on error
  19.340   * 
  19.341 - * @see scstrsplit_a()
  19.342 - */
  19.343 -sstr_t* scstrsplit(scstr_t string, scstr_t delim, ssize_t *count);
  19.344 -
  19.345 -/**
  19.346 - * Alias for scstrsplit() which automatically converts the arguments.
  19.347 - * 
  19.348 - * @param string the string to split
  19.349 - * @param delim  the delimiter string
  19.350 - * @param count  IN: the maximum size of the resulting array (0 = no limit),
  19.351 - *               OUT: the actual size of the array
  19.352 - * @return a sstr_t array containing the split strings or
  19.353 - * <code>NULL</code> on error
  19.354 - * 
  19.355   * @see sstrsplit_a()
  19.356   */
  19.357  #define sstrsplit(string, delim, count) \
  19.358 @@ -633,9 +701,6 @@
  19.359   * the sstr_t array itself are allocated by using the UcxAllocator.malloc()
  19.360   * function.
  19.361   * 
  19.362 - * <b>Note:</b> the allocator is not used for memory that is freed within the
  19.363 - * same call of this function (locally scoped variables).
  19.364 - * 
  19.365   * @param allocator the UcxAllocator used for allocating memory
  19.366   * @param string the string to split
  19.367   * @param delim  the delimiter string
  19.368 @@ -650,7 +715,13 @@
  19.369          ssize_t *count);
  19.370  
  19.371  /**
  19.372 - * Alias for scstrsplit_a() which automatically converts the arguments.
  19.373 + * Performing sstrsplit() using a UcxAllocator.
  19.374 + * 
  19.375 + * <i>Read the description of sstrsplit() for details.</i>
  19.376 + * 
  19.377 + * The memory for the sstr_t.ptr pointers of the array items and the memory for
  19.378 + * the sstr_t array itself are allocated by using the UcxAllocator.malloc()
  19.379 + * function.
  19.380   * 
  19.381   * @param allocator the UcxAllocator used for allocating memory
  19.382   * @param string the string to split
  19.383 @@ -680,7 +751,10 @@
  19.384  int scstrcmp(scstr_t s1, scstr_t s2);
  19.385  
  19.386  /**
  19.387 - * Alias for scstrcmp() which automatically converts its arguments.
  19.388 + * Compares two UCX strings with standard <code>memcmp()</code>.
  19.389 + * 
  19.390 + * At first it compares the sstr_t.length attribute of the two strings. The
  19.391 + * <code>memcmp()</code> function is called, if and only if the lengths match.
  19.392   * 
  19.393   * @param s1 the first string
  19.394   * @param s2 the second string
  19.395 @@ -706,7 +780,11 @@
  19.396  int scstrcasecmp(scstr_t s1, scstr_t s2);
  19.397  
  19.398  /**
  19.399 - * Alias for scstrcasecmp() which automatically converts the arguments.
  19.400 + * Compares two UCX strings ignoring the case.
  19.401 + * 
  19.402 + * At first it compares the sstr_t.length attribute of the two strings. If and
  19.403 + * only if the lengths match, both strings are compared char by char ignoring
  19.404 + * the case.
  19.405   * 
  19.406   * @param s1 the first string
  19.407   * @param s2 the second string
  19.408 @@ -733,7 +811,14 @@
  19.409  sstr_t scstrdup(scstr_t string);
  19.410  
  19.411  /**
  19.412 - * Alias for scstrdup() which automatically converts the argument.
  19.413 + * Creates a duplicate of the specified string.
  19.414 + * 
  19.415 + * The new sstr_t will contain a copy allocated by standard
  19.416 + * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to
  19.417 + * <code>free()</code>.
  19.418 + * 
  19.419 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
  19.420 + * terminated, regardless of the argument.
  19.421   * 
  19.422   * @param string the string to duplicate
  19.423   * @return a duplicate of the string
  19.424 @@ -760,7 +845,15 @@
  19.425  sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t string);
  19.426  
  19.427  /**
  19.428 - * Alias for scstrdup_a() which automatically converts the argument.
  19.429 + * Creates a duplicate of the specified string using a UcxAllocator.
  19.430 + * 
  19.431 + * The new sstr_t will contain a copy allocated by the allocators
  19.432 + * UcxAllocator.malloc() function. So it is implementation depended, whether the
  19.433 + * returned sstr_t.ptr pointer must be passed to the allocators
  19.434 + * UcxAllocator.free() function manually.
  19.435 + * 
  19.436 + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
  19.437 + * terminated, regardless of the argument.
  19.438   * 
  19.439   * @param allocator a valid instance of a UcxAllocator
  19.440   * @param string the string to duplicate
  19.441 @@ -810,6 +903,7 @@
  19.442  
  19.443  /**
  19.444   * Checks, if a string has a specific prefix.
  19.445 + * 
  19.446   * @param string the string to check
  19.447   * @param prefix the prefix the string should have
  19.448   * @return 1, if and only if the string has the specified prefix, 0 otherwise
  19.449 @@ -817,7 +911,7 @@
  19.450  int scstrprefix(scstr_t string, scstr_t prefix);
  19.451  
  19.452  /**
  19.453 - * Alias for scstrprefix() which automatically converts the arguments.
  19.454 + * Checks, if a string has a specific prefix.
  19.455   * 
  19.456   * @param string the string to check
  19.457   * @param prefix the prefix the string should have
  19.458 @@ -827,6 +921,7 @@
  19.459  
  19.460  /**
  19.461   * Checks, if a string has a specific suffix.
  19.462 + * 
  19.463   * @param string the string to check
  19.464   * @param suffix the suffix the string should have
  19.465   * @return 1, if and only if the string has the specified suffix, 0 otherwise
  19.466 @@ -834,7 +929,7 @@
  19.467  int scstrsuffix(scstr_t string, scstr_t suffix);
  19.468  
  19.469  /**
  19.470 - * Alias for scstrsuffix() which automatically converts the arguments.
  19.471 + * Checks, if a string has a specific suffix.
  19.472   *
  19.473   * @param string the string to check
  19.474   * @param suffix the suffix the string should have
  19.475 @@ -843,10 +938,48 @@
  19.476  #define sstrsuffix(string, suffix) scstrsuffix(SCSTR(string), SCSTR(suffix))
  19.477  
  19.478  /**
  19.479 + * Checks, if a string has a specific prefix, ignoring the case.
  19.480 + * 
  19.481 + * @param string the string to check
  19.482 + * @param prefix the prefix the string should have
  19.483 + * @return 1, if and only if the string has the specified prefix, 0 otherwise
  19.484 + */
  19.485 +int scstrcaseprefix(scstr_t string, scstr_t prefix);
  19.486 +
  19.487 +/**
  19.488 + * Checks, if a string has a specific prefix, ignoring the case.
  19.489 + * 
  19.490 + * @param string the string to check
  19.491 + * @param prefix the prefix the string should have
  19.492 + * @return 1, if and only if the string has the specified prefix, 0 otherwise
  19.493 + */
  19.494 +#define sstrcaseprefix(string, prefix) \
  19.495 +  scstrcaseprefix(SCSTR(string), SCSTR(prefix))
  19.496 +
  19.497 +/**
  19.498 + * Checks, if a string has a specific suffix, ignoring the case.
  19.499 + * 
  19.500 + * @param string the string to check
  19.501 + * @param suffix the suffix the string should have
  19.502 + * @return 1, if and only if the string has the specified suffix, 0 otherwise
  19.503 + */
  19.504 +int scstrcasesuffix(scstr_t string, scstr_t suffix);
  19.505 +
  19.506 +/**
  19.507 + * Checks, if a string has a specific suffix, ignoring the case.
  19.508 + *
  19.509 + * @param string the string to check
  19.510 + * @param suffix the suffix the string should have
  19.511 + * @return 1, if and only if the string has the specified suffix, 0 otherwise
  19.512 + */
  19.513 +#define sstrcasesuffix(string, suffix) \
  19.514 +  scstrcasesuffix(SCSTR(string), SCSTR(suffix))
  19.515 +
  19.516 +/**
  19.517   * Returns a lower case version of a string.
  19.518   * 
  19.519 - * This function creates a duplicate of the input string, first. See the
  19.520 - * documentation of scstrdup() for the implications.
  19.521 + * This function creates a duplicate of the input string, first
  19.522 + * (see scstrdup()).
  19.523   * 
  19.524   * @param string the input string
  19.525   * @return the resulting lower case string
  19.526 @@ -855,7 +988,10 @@
  19.527  sstr_t scstrlower(scstr_t string);
  19.528  
  19.529  /**
  19.530 - * Alias for scstrlower() which automatically converts the argument.
  19.531 + * Returns a lower case version of a string.
  19.532 + * 
  19.533 + * This function creates a duplicate of the input string, first
  19.534 + * (see sstrdup()).
  19.535   * 
  19.536   * @param string the input string
  19.537   * @return the resulting lower case string
  19.538 @@ -865,8 +1001,8 @@
  19.539  /**
  19.540   * Returns a lower case version of a string.
  19.541   * 
  19.542 - * This function creates a duplicate of the input string, first. See the
  19.543 - * documentation of scstrdup_a() for the implications.
  19.544 +  * This function creates a duplicate of the input string, first
  19.545 + * (see scstrdup_a()).
  19.546   * 
  19.547   * @param allocator the allocator used for duplicating the string
  19.548   * @param string the input string
  19.549 @@ -877,7 +1013,10 @@
  19.550  
  19.551  
  19.552  /**
  19.553 - * Alias for scstrlower_a() which automatically converts the argument.
  19.554 + * Returns a lower case version of a string.
  19.555 + * 
  19.556 + * This function creates a duplicate of the input string, first
  19.557 + * (see sstrdup_a()).
  19.558   * 
  19.559   * @param allocator the allocator used for duplicating the string
  19.560   * @param string the input string
  19.561 @@ -888,8 +1027,8 @@
  19.562  /**
  19.563   * Returns a upper case version of a string.
  19.564   * 
  19.565 - * This function creates a duplicate of the input string, first. See the
  19.566 - * documentation of scstrdup() for the implications.
  19.567 + * This function creates a duplicate of the input string, first
  19.568 + * (see scstrdup()).
  19.569   * 
  19.570   * @param string the input string
  19.571   * @return the resulting upper case string
  19.572 @@ -898,7 +1037,10 @@
  19.573  sstr_t scstrupper(scstr_t string);
  19.574  
  19.575  /**
  19.576 - * Alias for scstrupper() which automatically converts the argument.
  19.577 + * Returns a upper case version of a string.
  19.578 + * 
  19.579 + * This function creates a duplicate of the input string, first
  19.580 + * (see sstrdup()).
  19.581   * 
  19.582   * @param string the input string
  19.583   * @return the resulting upper case string
  19.584 @@ -908,8 +1050,8 @@
  19.585  /**
  19.586   * Returns a upper case version of a string.
  19.587   * 
  19.588 - * This function creates a duplicate of the input string, first. See the
  19.589 - * documentation of scstrdup_a() for the implications.
  19.590 + * This function creates a duplicate of the input string, first
  19.591 + * (see scstrdup_a()).
  19.592   * 
  19.593   * @param allocator the allocator used for duplicating the string
  19.594   * @param string the input string
  19.595 @@ -919,7 +1061,10 @@
  19.596  sstr_t scstrupper_a(UcxAllocator *allocator, scstr_t string);
  19.597  
  19.598  /**
  19.599 - * Alias for scstrupper_a() which automatically converts the argument.
  19.600 + * Returns a upper case version of a string.
  19.601 + * 
  19.602 + * This function creates a duplicate of the input string, first
  19.603 + * (see sstrdup_a()).
  19.604   * 
  19.605   * @param allocator the allocator used for duplicating the string
  19.606   * @param string the input string
  19.607 @@ -927,6 +1072,128 @@
  19.608   */
  19.609  #define sstrupper_a(allocator, string) scstrupper_a(allocator, string)
  19.610  
  19.611 +
  19.612 +/**
  19.613 + * Replaces a pattern in a string with another string.
  19.614 + *
  19.615 + * The pattern is taken literally and is no regular expression.
  19.616 + * Replaces at most <code>replmax</code> occurrences.
  19.617 + *
  19.618 + * The resulting string is allocated by the specified allocator. I.e. it
  19.619 + * depends on the used allocator, whether the sstr_t.ptr must be freed
  19.620 + * manually.
  19.621 + *
  19.622 + * If allocation fails, the sstr_t.ptr of the return value is NULL.
  19.623 + *
  19.624 + * @param allocator the allocator to use
  19.625 + * @param str the string where replacements should be applied
  19.626 + * @param pattern the pattern to search for
  19.627 + * @param replacement the replacement string
  19.628 + * @param replmax maximum number of replacements
  19.629 + * @return the resulting string after applying the replacements
  19.630 + */
  19.631 +sstr_t scstrreplacen_a(UcxAllocator *allocator, scstr_t str,
  19.632 +        scstr_t pattern, scstr_t replacement, size_t replmax);
  19.633 +
  19.634 +/**
  19.635 + * Replaces a pattern in a string with another string.
  19.636 + *
  19.637 + * The pattern is taken literally and is no regular expression.
  19.638 + * Replaces at most <code>replmax</code> occurrences.
  19.639 + *
  19.640 + * The sstr_t.ptr of the resulting string must be freed manually.
  19.641 + *
  19.642 + * If allocation fails, the sstr_t.ptr of the return value is NULL.
  19.643 + *
  19.644 + * @param str the string where replacements should be applied
  19.645 + * @param pattern the pattern to search for
  19.646 + * @param replacement the replacement string
  19.647 + * @param replmax maximum number of replacements
  19.648 + * @return the resulting string after applying the replacements
  19.649 + */
  19.650 +sstr_t scstrreplacen(scstr_t str, scstr_t pattern,
  19.651 +        scstr_t replacement, size_t replmax);
  19.652 +
  19.653 +/**
  19.654 + * Replaces a pattern in a string with another string.
  19.655 + *
  19.656 + * The pattern is taken literally and is no regular expression.
  19.657 + * Replaces at most <code>replmax</code> occurrences.
  19.658 + *
  19.659 + * The resulting string is allocated by the specified allocator. I.e. it
  19.660 + * depends on the used allocator, whether the sstr_t.ptr must be freed
  19.661 + * manually.
  19.662 + *
  19.663 + * @param allocator the allocator to use
  19.664 + * @param str the string where replacements should be applied
  19.665 + * @param pattern the pattern to search for
  19.666 + * @param replacement the replacement string
  19.667 + * @param replmax maximum number of replacements
  19.668 + * @return the resulting string after applying the replacements
  19.669 + */
  19.670 +#define sstrreplacen_a(allocator, str, pattern, replacement, replmax) \
  19.671 +        scstrreplacen_a(allocator, SCSTR(str), SCSTR(pattern), \
  19.672 +            SCSTR(replacement), replmax)
  19.673 +
  19.674 +/**
  19.675 + * Replaces a pattern in a string with another string.
  19.676 + *
  19.677 + * The pattern is taken literally and is no regular expression.
  19.678 + * Replaces at most <code>replmax</code> occurrences.
  19.679 + *
  19.680 + * The sstr_t.ptr of the resulting string must be freed manually.
  19.681 + *
  19.682 + * If allocation fails, the sstr_t.ptr of the return value is NULL.
  19.683 + *
  19.684 + * @param str the string where replacements should be applied
  19.685 + * @param pattern the pattern to search for
  19.686 + * @param replacement the replacement string
  19.687 + * @param replmax maximum number of replacements
  19.688 + * @return the resulting string after applying the replacements
  19.689 + */
  19.690 +#define sstrreplacen(str, pattern, replacement, replmax) \
  19.691 +        scstrreplacen(SCSTR(str), SCSTR(pattern), SCSTR(replacement), replmax)
  19.692 +
  19.693 +/**
  19.694 + * Replaces a pattern in a string with another string.
  19.695 + *
  19.696 + * The pattern is taken literally and is no regular expression.
  19.697 + * Replaces at most <code>replmax</code> occurrences.
  19.698 + *
  19.699 + * The resulting string is allocated by the specified allocator. I.e. it
  19.700 + * depends on the used allocator, whether the sstr_t.ptr must be freed
  19.701 + * manually.
  19.702 + *
  19.703 + * If allocation fails, the sstr_t.ptr of the return value is NULL.
  19.704 + *
  19.705 + * @param allocator the allocator to use
  19.706 + * @param str the string where replacements should be applied
  19.707 + * @param pattern the pattern to search for
  19.708 + * @param replacement the replacement string
  19.709 + * @return the resulting string after applying the replacements
  19.710 + */
  19.711 +#define sstrreplace_a(allocator, str, pattern, replacement) \
  19.712 +        scstrreplacen_a(allocator, SCSTR(str), SCSTR(pattern), \
  19.713 +            SCSTR(replacement), SIZE_MAX)
  19.714 +
  19.715 +/**
  19.716 + * Replaces a pattern in a string with another string.
  19.717 + *
  19.718 + * The pattern is taken literally and is no regular expression.
  19.719 + * Replaces at most <code>replmax</code> occurrences.
  19.720 + *
  19.721 + * The sstr_t.ptr of the resulting string must be freed manually.
  19.722 + *
  19.723 + * If allocation fails, the sstr_t.ptr of the return value is NULL.
  19.724 + *
  19.725 + * @param str the string where replacements should be applied
  19.726 + * @param pattern the pattern to search for
  19.727 + * @param replacement the replacement string
  19.728 + * @return the resulting string after applying the replacements
  19.729 + */
  19.730 +#define sstrreplace(str, pattern, replacement) \
  19.731 +        scstrreplacen(SCSTR(str), SCSTR(pattern), SCSTR(replacement), SIZE_MAX)
  19.732 +
  19.733  #ifdef	__cplusplus
  19.734  }
  19.735  #endif
    20.1 --- a/src/ucx/ucx.h	Mon Dec 30 09:52:07 2019 +0100
    20.2 +++ b/src/ucx/ucx.h	Mon Dec 30 09:52:44 2019 +0100
    20.3 @@ -1,7 +1,7 @@
    20.4  /*
    20.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    20.6   *
    20.7 - * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved.
    20.8 + * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
    20.9   *
   20.10   * Redistribution and use in source and binary forms, with or without
   20.11   * modification, are permitted provided that the following conditions are met:
   20.12 @@ -170,10 +170,7 @@
   20.13  
   20.14  /**
   20.15   * Performs a multiplication of size_t values and checks for overflow.
   20.16 - * 
   20.17 - * This is a custom implementation in case there is no compiler builtin
   20.18 - * available.
   20.19 - * 
   20.20 +  *
   20.21   * @param a first operand
   20.22   * @param b second operand
   20.23   * @param result a pointer to a size_t, where the result should
   20.24 @@ -183,6 +180,18 @@
   20.25   */
   20.26  #define ucx_szmul(a, b, result) ucx_szmul_impl(a, b, result)
   20.27  
   20.28 +/**
   20.29 + * Performs a multiplication of size_t values and checks for overflow.
   20.30 + *
   20.31 + * This is a custom implementation in case there is no compiler builtin
   20.32 + * available.
   20.33 + *
   20.34 + * @param a first operand
   20.35 + * @param b second operand
   20.36 + * @param result a pointer to a size_t where the result should be stored
   20.37 + * @return zero, if no overflow occurred and the result is correct, non-zero
   20.38 + * otherwise
   20.39 + */
   20.40  int ucx_szmul_impl(size_t a, size_t b, size_t *result);
   20.41  
   20.42  #endif
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/CMakeLists.txt	Mon Dec 30 09:52:44 2019 +0100
    21.3 @@ -0,0 +1,17 @@
    21.4 +add_executable(ucxtest
    21.5 +        allocator_tests.c
    21.6 +        array_tests.c
    21.7 +        avl_tests.c
    21.8 +        buffer_tests.c
    21.9 +        list_tests.c
   21.10 +        logging_tests.c
   21.11 +        main.c
   21.12 +        map_tests.c
   21.13 +        mpool_tests.c
   21.14 +        prop_tests.c
   21.15 +        stack_tests.c
   21.16 +        string_tests.c
   21.17 +        utils_tests.c
   21.18 +)
   21.19 +
   21.20 +target_link_libraries(ucxtest PRIVATE ucx_static)
    22.1 --- a/test/Makefile.am	Mon Dec 30 09:52:07 2019 +0100
    22.2 +++ b/test/Makefile.am	Mon Dec 30 09:52:44 2019 +0100
    22.3 @@ -29,6 +29,7 @@
    22.4  TESTS = ucxtest
    22.5  check_PROGRAMS = ucxtest
    22.6  ucxtest_CFLAGS = -I$(top_srcdir)/src
    22.7 +
    22.8  ucxtest_SOURCES = main.c
    22.9  ucxtest_SOURCES += allocator_tests.c
   22.10  ucxtest_SOURCES += array_tests.c
   22.11 @@ -42,5 +43,20 @@
   22.12  ucxtest_SOURCES += logging_tests.c
   22.13  ucxtest_SOURCES += buffer_tests.c
   22.14  ucxtest_SOURCES += utils_tests.c
   22.15 +
   22.16 +ucxtest_SOURCES += main.h
   22.17 +ucxtest_SOURCES += allocator_tests.h
   22.18 +ucxtest_SOURCES += array_tests.h
   22.19 +ucxtest_SOURCES += list_tests.h
   22.20 +ucxtest_SOURCES += avl_tests.h
   22.21 +ucxtest_SOURCES += mpool_tests.h
   22.22 +ucxtest_SOURCES += stack_tests.h
   22.23 +ucxtest_SOURCES += map_tests.h
   22.24 +ucxtest_SOURCES += prop_tests.h
   22.25 +ucxtest_SOURCES += string_tests.h
   22.26 +ucxtest_SOURCES += logging_tests.h
   22.27 +ucxtest_SOURCES += buffer_tests.h
   22.28 +ucxtest_SOURCES += utils_tests.h
   22.29 +
   22.30  ucxtest_LDFLAGS = -static
   22.31  ucxtest_LDADD = ../src/libucx.la
    23.1 --- a/test/array_tests.c	Mon Dec 30 09:52:07 2019 +0100
    23.2 +++ b/test/array_tests.c	Mon Dec 30 09:52:44 2019 +0100
    23.3 @@ -96,6 +96,48 @@
    23.4      ucx_array_free(array);
    23.5  }
    23.6  
    23.7 +UCX_TEST(test_ucx_array_append_from_struct) {
    23.8 +    struct teststruct {
    23.9 +        unsigned long long x;
   23.10 +        unsigned long long y;
   23.11 +        unsigned long long z;
   23.12 +    };
   23.13 +    
   23.14 +    UcxArray *array = ucx_array_new(16, sizeof(struct teststruct));
   23.15 +    struct teststruct *elements;
   23.16 +    
   23.17 +    struct teststruct data;
   23.18 +    data.x = 13; data.y = 37; data.z = 47;
   23.19 +    
   23.20 +    ucx_array_append_from(array, &data, 1);
   23.21 +    UCX_TEST_BEGIN
   23.22 +    
   23.23 +    elements = array->data;
   23.24 +    UCX_TEST_ASSERT(elements[0].x == 13, "failed");
   23.25 +    UCX_TEST_ASSERT(elements[0].y == 37, "failed");
   23.26 +    UCX_TEST_ASSERT(elements[0].z == 47, "failed");
   23.27 +    
   23.28 +    data.x = 0; data.y = 8; data.z = 15;
   23.29 +    ucx_array_append_from(array, &data, 1);
   23.30 +    
   23.31 +    elements = array->data;
   23.32 +    UCX_TEST_ASSERT(array->size == 2, "incorrect size after append");
   23.33 +    UCX_TEST_ASSERT(elements[1].x == 0, "failed");
   23.34 +    UCX_TEST_ASSERT(elements[1].y == 8, "failed");
   23.35 +    UCX_TEST_ASSERT(elements[1].z == 15, "failed");
   23.36 +    
   23.37 +    UCX_TEST_ASSERT(elements[0].x == 13,
   23.38 +            "append corrupted previously inserted data");
   23.39 +    UCX_TEST_ASSERT(elements[0].y == 37,
   23.40 +            "append corrupted previously inserted data");
   23.41 +    UCX_TEST_ASSERT(elements[0].z == 47,
   23.42 +            "append corrupted previously inserted data");
   23.43 +    
   23.44 +    UCX_TEST_END
   23.45 +    
   23.46 +    ucx_array_destroy(array);
   23.47 +}
   23.48 +
   23.49  UCX_TEST(test_ucx_array_prepend_from) {
   23.50      int *elems;
   23.51      UcxArray *array = ucx_array_new(16, sizeof(int));
   23.52 @@ -170,82 +212,6 @@
   23.53      ucx_array_free(array);
   23.54  }
   23.55  
   23.56 -UCX_TEST(test_ucx_array_append) {
   23.57 -    UcxArray *array = ucx_array_new(16, sizeof(int));
   23.58 -    int *elements;
   23.59 -    
   23.60 -    ucx_array_append(array, 42);
   23.61 -    UCX_TEST_BEGIN
   23.62 -    
   23.63 -    elements = array->data;
   23.64 -    UCX_TEST_ASSERT(elements[0] == 42, "failed");
   23.65 -    
   23.66 -    ucx_array_append(array, 13);
   23.67 -    ucx_array_append(array, 37);
   23.68 -    
   23.69 -    elements = array->data;
   23.70 -    UCX_TEST_ASSERT(array->size == 3, "incorrect size after append");
   23.71 -    UCX_TEST_ASSERT(elements[1] == 13, "failed");
   23.72 -    UCX_TEST_ASSERT(elements[2] == 37, "failed");
   23.73 -    UCX_TEST_ASSERT(elements[0] == 42,
   23.74 -            "append corrupted previously inserted data");
   23.75 -    
   23.76 -    UCX_TEST_END
   23.77 -    
   23.78 -    ucx_array_destroy(array);
   23.79 -}
   23.80 -
   23.81 -UCX_TEST(test_ucx_array_prepend) {
   23.82 -    int *elems;
   23.83 -    UcxArray *array = ucx_array_new(16, sizeof(int));
   23.84 -    
   23.85 -    ucx_array_prepend(array, 42);
   23.86 -    UCX_TEST_BEGIN
   23.87 -    
   23.88 -    elems = array->data;
   23.89 -    UCX_TEST_ASSERT(elems[0] == 42, "failed");
   23.90 -    
   23.91 -    ucx_array_prepend(array, 37);
   23.92 -    ucx_array_prepend(array, 13);
   23.93 -    
   23.94 -    elems = array->data;
   23.95 -    UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend");
   23.96 -    UCX_TEST_ASSERT(elems[0] == 13, "failed");
   23.97 -    UCX_TEST_ASSERT(elems[1] == 37, "failed");
   23.98 -    UCX_TEST_ASSERT(elems[2] == 42,
   23.99 -            "prepend corrupted previously inserted data");
  23.100 -    
  23.101 -    UCX_TEST_END
  23.102 -    
  23.103 -    ucx_array_free(array);
  23.104 -}
  23.105 -
  23.106 -UCX_TEST(test_ucx_array_set) {
  23.107 -    int *elems;
  23.108 -    UcxArray *array = ucx_array_new(16, sizeof(int));
  23.109 -
  23.110 -    UCX_TEST_BEGIN
  23.111 -
  23.112 -    ucx_array_set(array, 7, 42);
  23.113 -    
  23.114 -    elems = array->data;
  23.115 -    UCX_TEST_ASSERT(elems[7] == 42, "failed");
  23.116 -    UCX_TEST_ASSERT(array->size == 8, "array not resized on set");
  23.117 -    UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily");
  23.118 -    
  23.119 -    ucx_array_set(array, 27, 13);
  23.120 -    ucx_array_set(array, 28, 37);
  23.121 -    
  23.122 -    elems = array->data;
  23.123 -    UCX_TEST_ASSERT(elems[27] == 13, "failed");
  23.124 -    UCX_TEST_ASSERT(elems[28] == 37, "failed");
  23.125 -    UCX_TEST_ASSERT(array->size == 29, "array not resized on set");
  23.126 -    UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown");
  23.127 -        
  23.128 -    UCX_TEST_END
  23.129 -    
  23.130 -    ucx_array_free(array);
  23.131 -}
  23.132  
  23.133  UCX_TEST(test_ucx_array_equals) {
  23.134      UcxArray *a1 = ucx_array_new(16, sizeof(int32_t));
  23.135 @@ -559,32 +525,6 @@
  23.136      ucx_array_free(array);
  23.137  }
  23.138  
  23.139 -UCX_TEST(test_ucx_array_autogrow) {
  23.140 -    int *elems;
  23.141 -    UcxArray *array = ucx_array_new(4, sizeof(int));
  23.142 -    array->size = 3;
  23.143 -    elems = array->data;
  23.144 -    elems[0] = 47;
  23.145 -    elems[1] = 11;
  23.146 -    int x = 5;
  23.147 -    
  23.148 -    UCX_TEST_BEGIN
  23.149 -
  23.150 -    void* oldptr = array->data;
  23.151 -    
  23.152 -    ucx_array_append(array, 5);
  23.153 -    UCX_TEST_ASSERT(array->capacity == 4 && array->data == oldptr,
  23.154 -            "array should not grow too early");
  23.155 -    ucx_array_append(array, 5);
  23.156 -    elems = array->data;
  23.157 -    UCX_TEST_ASSERT(array->capacity == 8, "array did not grow");
  23.158 -    UCX_TEST_ASSERT(array->size == 5, "incorrect size after grow");
  23.159 -    UCX_TEST_ASSERT(elems[3] == 5 && elems[4] == 5, "corrupt data");
  23.160 -    
  23.161 -    UCX_TEST_END
  23.162 -    ucx_array_free(array);
  23.163 -}
  23.164 -
  23.165  UCX_TEST(test_ucx_array_shrink) {
  23.166      UcxArray *array = ucx_array_new(16, sizeof(int));
  23.167      array->size = 4;
  23.168 @@ -629,19 +569,42 @@
  23.169      ucx_array_free(array);
  23.170  }
  23.171  
  23.172 +UCX_TEST(test_ucx_array_grow) {
  23.173 +    UcxArray *array = ucx_array_new(16, sizeof(int));
  23.174 +    array->size = 12;
  23.175 +    
  23.176 +    UCX_TEST_BEGIN
  23.177 +
  23.178 +    UCX_TEST_ASSERT(!ucx_array_grow(array, 4), "failed");
  23.179 +    UCX_TEST_ASSERT(array->capacity == 16, "shall be noop if contents fit");
  23.180 +    /* subsequent calls shall also be noops */
  23.181 +    UCX_TEST_ASSERT(!ucx_array_grow(array, 4), "failed");
  23.182 +    UCX_TEST_ASSERT(array->capacity == 16, "shall be noop if contents fit");
  23.183 +            
  23.184 +    UCX_TEST_ASSERT(!ucx_array_grow(array, 6), "failed");
  23.185 +    UCX_TEST_ASSERT(array->capacity == 18, "incorrect capacity after grow");    
  23.186 +    
  23.187 +    UCX_TEST_END
  23.188 +    ucx_array_free(array);
  23.189 +}
  23.190 +
  23.191  UCX_TEST(test_ucx_array_util_set) {
  23.192      size_t capacity = 16;
  23.193      int* array = malloc(sizeof(int)*capacity);
  23.194 +    int x;
  23.195  
  23.196      UCX_TEST_BEGIN
  23.197  
  23.198 -    UCX_ARRAY_UTIL_SET(&array, &capacity, 7, 42);
  23.199 +    x = 42;
  23.200 +    ucx_array_util_set(&array, &capacity, sizeof(int), 7, &x);
  23.201      
  23.202      UCX_TEST_ASSERT(array[7] == 42, "failed");
  23.203      UCX_TEST_ASSERT(capacity == 16, "capacity changed unnecessarily");
  23.204      
  23.205 -    UCX_ARRAY_UTIL_SET(&array, &capacity, 37, 13);
  23.206 -    UCX_ARRAY_UTIL_SET(&array, &capacity, 38, 37);
  23.207 +    x = 13;
  23.208 +    ucx_array_util_set(&array, &capacity, sizeof(int), 37, &x);
  23.209 +    x = 37;
  23.210 +    ucx_array_util_set(&array, &capacity, sizeof(int), 38, &x);
  23.211      
  23.212      UCX_TEST_ASSERT(array[37] == 13, "failed");
  23.213      UCX_TEST_ASSERT(array[38] == 37, "failed");
  23.214 @@ -651,3 +614,29 @@
  23.215      
  23.216      free(array);
  23.217  }
  23.218 +
  23.219 +
  23.220 +UCX_TEST(test_ucx_array_util_setptr) {
  23.221 +    size_t capacity = 16;
  23.222 +    double** array = malloc(sizeof(double*)*capacity);
  23.223 +    double x, y, z;
  23.224 +
  23.225 +    UCX_TEST_BEGIN
  23.226 +
  23.227 +    ucx_array_util_setptr(&array, &capacity, 7, &x);
  23.228 +    
  23.229 +    UCX_TEST_ASSERT(array[7] == &x, "failed");
  23.230 +    UCX_TEST_ASSERT(capacity == 16, "capacity changed unnecessarily");
  23.231 +    
  23.232 +    ucx_array_util_setptr(&array, &capacity, 37, &y);
  23.233 +    ucx_array_util_setptr(&array, &capacity, 38, &z);
  23.234 +    
  23.235 +    UCX_TEST_ASSERT(array[37] == &y, "failed");
  23.236 +    UCX_TEST_ASSERT(array[38] == &z, "failed");
  23.237 +    UCX_TEST_ASSERT(capacity == 64, "capacity not grown");
  23.238 +        
  23.239 +    UCX_TEST_END
  23.240 +    
  23.241 +    free(array);
  23.242 +}
  23.243 +
    24.1 --- a/test/array_tests.h	Mon Dec 30 09:52:07 2019 +0100
    24.2 +++ b/test/array_tests.h	Mon Dec 30 09:52:44 2019 +0100
    24.3 @@ -40,12 +40,9 @@
    24.4  UCX_TEST(test_ucx_array_new);
    24.5  UCX_TEST(test_ucx_array_at);
    24.6  UCX_TEST(test_ucx_array_append_from);
    24.7 +UCX_TEST(test_ucx_array_append_from_struct);
    24.8  UCX_TEST(test_ucx_array_prepend_from);
    24.9  UCX_TEST(test_ucx_array_set_from);
   24.10 -UCX_TEST(test_ucx_array_append);
   24.11 -UCX_TEST(test_ucx_array_prepend);
   24.12 -UCX_TEST(test_ucx_array_set);
   24.13 -UCX_TEST(test_ucx_array_autogrow);
   24.14  UCX_TEST(test_ucx_array_equals);
   24.15  UCX_TEST(test_ucx_array_concat);
   24.16  UCX_TEST(test_ucx_array_find);
   24.17 @@ -56,7 +53,9 @@
   24.18  UCX_TEST(test_ucx_array_shrink);
   24.19  UCX_TEST(test_ucx_array_resize);
   24.20  UCX_TEST(test_ucx_array_reserve);
   24.21 +UCX_TEST(test_ucx_array_grow);
   24.22  UCX_TEST(test_ucx_array_util_set);
   24.23 +UCX_TEST(test_ucx_array_util_setptr);
   24.24  
   24.25  #ifdef	__cplusplus
   24.26  }
    25.1 --- a/test/list_tests.c	Mon Dec 30 09:52:07 2019 +0100
    25.2 +++ b/test/list_tests.c	Mon Dec 30 09:52:44 2019 +0100
    25.3 @@ -403,3 +403,94 @@
    25.4      ucx_list_free(expected);
    25.5      ucx_list_free(list);
    25.6  }
    25.7 +
    25.8 +UCX_TEST(test_ucx_list_union) {
    25.9 +    UcxList *left = ucx_list_append(NULL, (void*)"this");
   25.10 +    left = ucx_list_append(left, (void*)"is");
   25.11 +    left = ucx_list_append(left, (void*)"a");
   25.12 +    left = ucx_list_append(left, (void*)"test");
   25.13 +
   25.14 +    UcxList *right = ucx_list_append(NULL, (void*)"to");
   25.15 +    right = ucx_list_append(right, (void*)"test");
   25.16 +    right = ucx_list_append(right, (void*)"set");
   25.17 +    right = ucx_list_append(right, (void*)"operations");
   25.18 +    
   25.19 +    UcxList *expected = ucx_list_append(NULL, (void*)"this");
   25.20 +    expected = ucx_list_append(expected, (void*)"is");
   25.21 +    expected = ucx_list_append(expected, (void*)"a");
   25.22 +    expected = ucx_list_append(expected, (void*)"test");
   25.23 +    expected = ucx_list_append(expected, (void*)"to");
   25.24 +    expected = ucx_list_append(expected, (void*)"set");
   25.25 +    expected = ucx_list_append(expected, (void*)"operations");
   25.26 +
   25.27 +    UcxList* result = ucx_list_union(left, right, ucx_cmp_str,
   25.28 +            NULL, NULL, NULL);
   25.29 +
   25.30 +    UCX_TEST_BEGIN
   25.31 +    UCX_TEST_ASSERT(ucx_list_equals(result, expected,
   25.32 +            ucx_cmp_str, NULL), "failed");
   25.33 +    UCX_TEST_END
   25.34 +
   25.35 +    ucx_list_free(result);
   25.36 +    ucx_list_free(expected);
   25.37 +    ucx_list_free(right);
   25.38 +    ucx_list_free(left);
   25.39 +}
   25.40 +
   25.41 +UCX_TEST(test_ucx_list_intersection) {
   25.42 +    UcxList *left = ucx_list_append(NULL, (void*)"this");
   25.43 +    left = ucx_list_append(left, (void*)"is");
   25.44 +    left = ucx_list_append(left, (void*)"a");
   25.45 +    left = ucx_list_append(left, (void*)"test");
   25.46 +
   25.47 +    UcxList *right = ucx_list_append(NULL, (void*)"to");
   25.48 +    right = ucx_list_append(right, (void*)"test");
   25.49 +    right = ucx_list_append(right, (void*)"a");
   25.50 +    right = ucx_list_append(right, (void*)"set");
   25.51 +    right = ucx_list_append(right, (void*)"operation");
   25.52 +    
   25.53 +    UcxList *expected = ucx_list_append(NULL, (void*)"a");
   25.54 +    expected = ucx_list_append(expected, (void*)"test");
   25.55 +
   25.56 +    UcxList* result = ucx_list_intersection(left, right, ucx_cmp_str,
   25.57 +            NULL, NULL, NULL);
   25.58 +
   25.59 +    UCX_TEST_BEGIN
   25.60 +    UCX_TEST_ASSERT(ucx_list_equals(result, expected,
   25.61 +            ucx_cmp_str, NULL), "failed");
   25.62 +    UCX_TEST_END
   25.63 +
   25.64 +    ucx_list_free(result);
   25.65 +    ucx_list_free(expected);
   25.66 +    ucx_list_free(right);
   25.67 +    ucx_list_free(left);
   25.68 +}
   25.69 +
   25.70 +UCX_TEST(test_ucx_list_difference) {
   25.71 +    UcxList *left = ucx_list_append(NULL, (void*)"this");
   25.72 +    left = ucx_list_append(left, (void*)"is");
   25.73 +    left = ucx_list_append(left, (void*)"a");
   25.74 +    left = ucx_list_append(left, (void*)"test");
   25.75 +
   25.76 +    UcxList *right = ucx_list_append(NULL, (void*)"to");
   25.77 +    right = ucx_list_append(right, (void*)"test");
   25.78 +    right = ucx_list_append(right, (void*)"this");
   25.79 +    right = ucx_list_append(right, (void*)"set");
   25.80 +    right = ucx_list_append(right, (void*)"operations");
   25.81 +    
   25.82 +    UcxList *expected = ucx_list_append(NULL, (void*)"is");
   25.83 +    expected = ucx_list_append(expected, (void*)"a");
   25.84 +    
   25.85 +    UcxList* result = ucx_list_difference(left, right, ucx_cmp_str,
   25.86 +            NULL, NULL, NULL);
   25.87 +
   25.88 +    UCX_TEST_BEGIN
   25.89 +    UCX_TEST_ASSERT(ucx_list_equals(result, expected,
   25.90 +            ucx_cmp_str, NULL), "failed");
   25.91 +    UCX_TEST_END
   25.92 +
   25.93 +    ucx_list_free(result);
   25.94 +    ucx_list_free(expected);
   25.95 +    ucx_list_free(right);
   25.96 +    ucx_list_free(left);
   25.97 +}
    26.1 --- a/test/list_tests.h	Mon Dec 30 09:52:07 2019 +0100
    26.2 +++ b/test/list_tests.h	Mon Dec 30 09:52:44 2019 +0100
    26.3 @@ -55,6 +55,9 @@
    26.4  UCX_TEST(test_ucx_list_remove);
    26.5  UCX_TEST(test_ucx_list_clone);
    26.6  UCX_TEST(test_ucx_list_sort);
    26.7 +UCX_TEST(test_ucx_list_union);
    26.8 +UCX_TEST(test_ucx_list_intersection);
    26.9 +UCX_TEST(test_ucx_list_difference);
   26.10  
   26.11  #ifdef	__cplusplus
   26.12  }
    27.1 --- a/test/main.c	Mon Dec 30 09:52:07 2019 +0100
    27.2 +++ b/test/main.c	Mon Dec 30 09:52:44 2019 +0100
    27.3 @@ -137,6 +137,8 @@
    27.4          ucx_test_register(suite, test_sstrsplit);
    27.5          ucx_test_register(suite, test_sstrtrim);
    27.6          ucx_test_register(suite, test_sstrprefixsuffix);
    27.7 +        ucx_test_register(suite, test_sstrcaseprefixsuffix);
    27.8 +        ucx_test_register(suite, test_sstrreplace);
    27.9          
   27.10          /* UcxLogger Tests */
   27.11          ucx_test_register(suite, test_ucx_logger_new);
   27.12 @@ -147,12 +149,9 @@
   27.13          ucx_test_register(suite, test_ucx_array_new);
   27.14          ucx_test_register(suite, test_ucx_array_at);
   27.15          ucx_test_register(suite, test_ucx_array_append_from);
   27.16 +        ucx_test_register(suite, test_ucx_array_append_from_struct);
   27.17          ucx_test_register(suite, test_ucx_array_prepend_from);
   27.18          ucx_test_register(suite, test_ucx_array_set_from);
   27.19 -        ucx_test_register(suite, test_ucx_array_append);
   27.20 -        ucx_test_register(suite, test_ucx_array_prepend);
   27.21 -        ucx_test_register(suite, test_ucx_array_set);
   27.22 -        ucx_test_register(suite, test_ucx_array_autogrow);
   27.23          ucx_test_register(suite, test_ucx_array_equals);
   27.24          ucx_test_register(suite, test_ucx_array_concat);
   27.25          ucx_test_register(suite, test_ucx_array_find);
   27.26 @@ -163,7 +162,9 @@
   27.27          ucx_test_register(suite, test_ucx_array_shrink);
   27.28          ucx_test_register(suite, test_ucx_array_resize);
   27.29          ucx_test_register(suite, test_ucx_array_reserve);
   27.30 +        ucx_test_register(suite, test_ucx_array_grow);
   27.31          ucx_test_register(suite, test_ucx_array_util_set);
   27.32 +        ucx_test_register(suite, test_ucx_array_util_setptr);
   27.33          
   27.34          /* UcxList Tests */
   27.35          ucx_test_register(suite, test_ucx_list_append);
   27.36 @@ -180,6 +181,9 @@
   27.37          ucx_test_register(suite, test_ucx_list_remove);
   27.38          ucx_test_register(suite, test_ucx_list_clone);
   27.39          ucx_test_register(suite, test_ucx_list_sort);
   27.40 +        ucx_test_register(suite, test_ucx_list_union);
   27.41 +        ucx_test_register(suite, test_ucx_list_intersection);
   27.42 +        ucx_test_register(suite, test_ucx_list_difference);
   27.43  
   27.44          /* UcxMemPool Tests */
   27.45          ucx_test_register(suite, test_ucx_mempool_new);
   27.46 @@ -210,6 +214,9 @@
   27.47          ucx_test_register(suite, test_ucx_map_iterator_chain);
   27.48          ucx_test_register(suite, test_ucx_map_clone);
   27.49          ucx_test_register(suite, test_ucx_map_rehash);
   27.50 +        ucx_test_register(suite, test_ucx_map_union);
   27.51 +        ucx_test_register(suite, test_ucx_map_intersection);
   27.52 +        ucx_test_register(suite, test_ucx_map_difference);
   27.53          
   27.54          /* UcxPropertiesParser Tests */
   27.55          ucx_test_register(suite, test_ucx_properties_new);
    28.1 --- a/test/map_tests.c	Mon Dec 30 09:52:07 2019 +0100
    28.2 +++ b/test/map_tests.c	Mon Dec 30 09:52:44 2019 +0100
    28.3 @@ -27,6 +27,7 @@
    28.4   */
    28.5  
    28.6  #include "map_tests.h"
    28.7 +#include <ucx/utils.h>
    28.8  
    28.9  UCX_TEST(test_ucx_map_new) {
   28.10      UcxMap *map = ucx_map_new(16);
   28.11 @@ -304,3 +305,127 @@
   28.12  
   28.13      ucx_map_free(map);
   28.14  }
   28.15 +
   28.16 +UCX_TEST(test_ucx_map_union) {
   28.17 +    int td[5];
   28.18 +    size_t intlen = sizeof(int);
   28.19 +    td[0] = 10; td[1] = 42; td[2] = 47; td[3] = 1337; td[4] = 9000;
   28.20 +
   28.21 +    UcxMap *first = ucx_map_new(4);
   28.22 +    UcxMap *second = ucx_map_new(4);
   28.23 +
   28.24 +    ucx_map_cstr_put(first, "key0", &td[0]);
   28.25 +    ucx_map_cstr_put(first, "key1", &td[1]);
   28.26 +    ucx_map_cstr_put(second, "key2", &td[2]);
   28.27 +    ucx_map_cstr_put(second, "key0", &td[3]);
   28.28 +    ucx_map_cstr_put(second, "key3", &td[4]);
   28.29 +
   28.30 +    UcxMap *result = ucx_map_union(first, second, ucx_memcpy, &intlen);
   28.31 +
   28.32 +    UCX_TEST_BEGIN
   28.33 +
   28.34 +    int* r;
   28.35 +    UCX_TEST_ASSERT(result->count == 4,
   28.36 +            "result has incorrect number of elements");
   28.37 +
   28.38 +    r = (int*)ucx_map_cstr_get(result, "key0");
   28.39 +    UCX_TEST_ASSERT(!!r, "key0 is not present");
   28.40 +    UCX_TEST_ASSERT(*r == td[3], "key0 has not been overwritten");
   28.41 +    r = (int*)ucx_map_cstr_get(result, "key1");
   28.42 +    UCX_TEST_ASSERT(!!r, "key1 is not present");
   28.43 +    UCX_TEST_ASSERT(*r == td[1], "key1 contains wrong data");
   28.44 +    r = (int*)ucx_map_cstr_get(result, "key2");
   28.45 +    UCX_TEST_ASSERT(!!r, "key2 is not present");
   28.46 +    UCX_TEST_ASSERT(*r == td[2], "key2 contains wrong data");
   28.47 +    r = (int*)ucx_map_cstr_get(result, "key3");
   28.48 +    UCX_TEST_ASSERT(!!r, "key3 is not present");
   28.49 +    UCX_TEST_ASSERT(*r == td[4], "key3 contains wrong data");
   28.50 +
   28.51 +    UCX_TEST_END
   28.52 +
   28.53 +    ucx_map_free_content(result, NULL);
   28.54 +    ucx_map_free(result);
   28.55 +    ucx_map_free(second);
   28.56 +    ucx_map_free(first);
   28.57 +}
   28.58 +
   28.59 +UCX_TEST(test_ucx_map_intersection) {
   28.60 +        int td[5];
   28.61 +        size_t intlen = sizeof(int);
   28.62 +        td[0] = 10; td[1] = 42; td[2] = 47; td[3] = 1337; td[4] = 9000;
   28.63 +
   28.64 +        UcxMap *first = ucx_map_new(4);
   28.65 +        UcxMap *second = ucx_map_new(4);
   28.66 +
   28.67 +        ucx_map_cstr_put(first, "key0", &td[0]);
   28.68 +        ucx_map_cstr_put(first, "key1", &td[1]);
   28.69 +        ucx_map_cstr_put(first, "key4", &td[3]);
   28.70 +        ucx_map_cstr_put(second, "key2", &td[2]);
   28.71 +        ucx_map_cstr_put(second, "key0", &td[3]);
   28.72 +        ucx_map_cstr_put(second, "key3", &td[4]);
   28.73 +        ucx_map_cstr_put(second, "key4", &td[4]);
   28.74 +
   28.75 +        UcxMap *result = ucx_map_intersection(first, second,
   28.76 +                ucx_memcpy, &intlen);
   28.77 +
   28.78 +        UCX_TEST_BEGIN
   28.79 +
   28.80 +        int* r;
   28.81 +        UCX_TEST_ASSERT(result->count == 2,
   28.82 +                "result has incorrect number of elements");
   28.83 +
   28.84 +        r = (int*)ucx_map_cstr_get(result, "key0");
   28.85 +        UCX_TEST_ASSERT(!!r, "key0 is not present");
   28.86 +        UCX_TEST_ASSERT(*r == td[0], "key0 has not original data");
   28.87 +        r = (int*)ucx_map_cstr_get(result, "key4");
   28.88 +        UCX_TEST_ASSERT(!!r, "key4 is not present");
   28.89 +        UCX_TEST_ASSERT(*r == td[3], "key4 has not original data");
   28.90 +
   28.91 +        UCX_TEST_END
   28.92 +
   28.93 +        ucx_map_free_content(result, NULL);
   28.94 +        ucx_map_free(result);
   28.95 +        ucx_map_free(second);
   28.96 +        ucx_map_free(first);
   28.97 +}
   28.98 +
   28.99 +
  28.100 +UCX_TEST(test_ucx_map_difference) {
  28.101 +        int td[5];
  28.102 +        size_t intlen = sizeof(int);
  28.103 +        td[0] = 10; td[1] = 42; td[2] = 47; td[3] = 1337; td[4] = 9000;
  28.104 +
  28.105 +        UcxMap *first = ucx_map_new(4);
  28.106 +        UcxMap *second = ucx_map_new(4);
  28.107 +
  28.108 +        ucx_map_cstr_put(first, "key0", &td[0]);
  28.109 +        ucx_map_cstr_put(first, "key1", &td[1]);
  28.110 +        ucx_map_cstr_put(first, "key2", &td[2]);
  28.111 +        ucx_map_cstr_put(first, "key4", &td[3]);
  28.112 +        ucx_map_cstr_put(second, "key0", &td[3]);
  28.113 +        ucx_map_cstr_put(second, "key3", &td[4]);
  28.114 +        ucx_map_cstr_put(second, "key4", &td[4]);
  28.115 +
  28.116 +        UcxMap *result = ucx_map_difference(first, second, ucx_memcpy, &intlen);
  28.117 +
  28.118 +        UCX_TEST_BEGIN
  28.119 +
  28.120 +        int* r;
  28.121 +        UCX_TEST_ASSERT(result->count == 2,
  28.122 +                "result has incorrect number of elements");
  28.123 +
  28.124 +        r = (int*)ucx_map_cstr_get(result, "key1");
  28.125 +        UCX_TEST_ASSERT(!!r, "key1 is not present");
  28.126 +        UCX_TEST_ASSERT(*r == td[1], "key1 has incorrect data");
  28.127 +        r = (int*)ucx_map_cstr_get(result, "key2");
  28.128 +        UCX_TEST_ASSERT(!!r, "key2 is not present");
  28.129 +        UCX_TEST_ASSERT(*r == td[2], "key2 has incorrect data");
  28.130 +
  28.131 +        UCX_TEST_END
  28.132 +
  28.133 +        ucx_map_free_content(result, NULL);
  28.134 +        ucx_map_free(result);
  28.135 +        ucx_map_free(second);
  28.136 +        ucx_map_free(first);
  28.137 +}
  28.138 +
    29.1 --- a/test/map_tests.h	Mon Dec 30 09:52:07 2019 +0100
    29.2 +++ b/test/map_tests.h	Mon Dec 30 09:52:44 2019 +0100
    29.3 @@ -46,6 +46,9 @@
    29.4  UCX_TEST(test_ucx_map_iterator_chain);
    29.5  UCX_TEST(test_ucx_map_clone);
    29.6  UCX_TEST(test_ucx_map_rehash);
    29.7 +UCX_TEST(test_ucx_map_union);
    29.8 +UCX_TEST(test_ucx_map_intersection);
    29.9 +UCX_TEST(test_ucx_map_difference);
   29.10  
   29.11  
   29.12  #ifdef	__cplusplus
    30.1 --- a/test/string_tests.c	Mon Dec 30 09:52:07 2019 +0100
    30.2 +++ b/test/string_tests.c	Mon Dec 30 09:52:44 2019 +0100
    30.3 @@ -452,3 +452,138 @@
    30.4      
    30.5      UCX_TEST_END
    30.6  }
    30.7 +
    30.8 +UCX_TEST(test_sstrcaseprefixsuffix) {
    30.9 +    sstr_t str = ST("test my prefix and my suffix");
   30.10 +    sstr_t empty = ST("");
   30.11 +    
   30.12 +    UCX_TEST_BEGIN
   30.13 +    
   30.14 +    UCX_TEST_ASSERT(!sstrcaseprefix(empty, S("pREf")), "prefix empty string fails");
   30.15 +    UCX_TEST_ASSERT(!sstrcasesuffix(empty, S("sUf")), "suffix empty string fails");
   30.16 +    
   30.17 +    UCX_TEST_ASSERT(sstrcaseprefix(str, empty), "empty prefix fails");
   30.18 +    UCX_TEST_ASSERT(sstrcasesuffix(str, empty), "empty suffix fails");
   30.19 +    
   30.20 +    UCX_TEST_ASSERT(sstrcaseprefix(empty, empty), "string and prefix empty fails");
   30.21 +    UCX_TEST_ASSERT(sstrcasesuffix(empty, empty), "string and suffix empty fails");
   30.22 +    
   30.23 +    UCX_TEST_ASSERT(sstrcaseprefix(str, S("TEST ")), "prefix false negative");
   30.24 +    UCX_TEST_ASSERT(!sstrcaseprefix(str, S("8-) fsck ")), "prefix false positive");
   30.25 +    
   30.26 +    UCX_TEST_ASSERT(sstrcasesuffix(str, S("FIX")), "suffix false negative");
   30.27 +    UCX_TEST_ASSERT(!sstrcasesuffix(str, S("fox")), "suffix false positive");
   30.28 +    
   30.29 +    UCX_TEST_END
   30.30 +}
   30.31 +
   30.32 +UCX_TEST(test_sstrreplace) {
   30.33 +
   30.34 +    sstr_t str = ST("test ababab string aba");
   30.35 +    sstr_t longstr = ST("xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd");
   30.36 +    sstr_t notrail = ST("test abab");
   30.37 +    sstr_t empty = ST("");
   30.38 +    sstr_t astr = ST("aaaaaaaaaa");
   30.39 +    sstr_t csstr = ST("test AB ab TEST xyz");
   30.40 +
   30.41 +    sstr_t repl = sstrreplace(str, SC("abab"), SC("muchlonger"));
   30.42 +    sstr_t expected = ST("test muchlongerab string aba");
   30.43 +
   30.44 +    sstr_t repln = sstrreplacen(str, SC("ab"), SC("c"), 2);
   30.45 +    sstr_t expectedn = ST("test ccab string aba");
   30.46 +
   30.47 +    sstr_t longrepl = sstrreplace(longstr, SC("a"), SC("z"));
   30.48 +    sstr_t longexpect = ST("xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd");
   30.49 +
   30.50 +    sstr_t replnotrail = sstrreplace(notrail, SC("ab"), SC("z"));
   30.51 +    sstr_t notrailexpect = ST("test zz");
   30.52 +    
   30.53 +    sstr_t repleq = sstrreplace(str, str, SC("hello"));
   30.54 +    sstr_t eqexpect = ST("hello");
   30.55 +    
   30.56 +    sstr_t replempty1 = sstrreplace(empty, SC("ab"), SC("c")); // expect: empty
   30.57 +    sstr_t replempty2 = sstrreplace(str, SC("abab"), empty);
   30.58 +    sstr_t emptyexpect2 = ST("test ab string aba");
   30.59 +    
   30.60 +    sstr_t replpre = sstrreplace(str, SC("test "), SC("TEST "));
   30.61 +    sstr_t preexpected = ST("TEST ababab string aba");
   30.62 +    
   30.63 +    sstr_t replan1 = sstrreplacen(astr, SC("a"), SC("x"), 1);
   30.64 +    sstr_t an1expected = ST("xaaaaaaaaa");
   30.65 +    
   30.66 +    sstr_t replan4 = sstrreplacen(astr, SC("a"), SC("x"), 4);
   30.67 +    sstr_t an4expected = ST("xxxxaaaaaa");
   30.68 +    
   30.69 +    sstr_t replan9 = sstrreplacen(astr, SC("a"), SC("x"), 9);
   30.70 +    sstr_t an9expected = ST("xxxxxxxxxa");
   30.71 +    
   30.72 +    sstr_t replan10 = sstrreplacen(astr, SC("a"), SC("x"), 10);
   30.73 +    sstr_t an10expected = ST("xxxxxxxxxx");
   30.74 +    
   30.75 +    sstr_t replcs1 = sstrreplace(csstr, SC("AB"), SC("*"));
   30.76 +    sstr_t cs1expected = ST("test * ab TEST xyz");
   30.77 +    
   30.78 +    sstr_t replcs2 = sstrreplace(csstr, SC("test"), SC("TEST"));
   30.79 +    sstr_t cs2expected = ST("TEST AB ab TEST xyz");
   30.80 +    
   30.81 +    UCX_TEST_BEGIN
   30.82 +
   30.83 +    UCX_TEST_ASSERT(repl.ptr != str.ptr, "result string is not fresh");
   30.84 +    UCX_TEST_ASSERT(!sstrcmp(repl, expected), "incorrect replacement");
   30.85 +
   30.86 +    UCX_TEST_ASSERT(repln.ptr != str.ptr, "result string is not fresh");
   30.87 +    UCX_TEST_ASSERT(!sstrcmp(repln, expectedn), "incorrect replacement");
   30.88 +
   30.89 +    UCX_TEST_ASSERT(!sstrcmp(longrepl, longexpect),
   30.90 +            "incorrect handling of long strings");
   30.91 +
   30.92 +    UCX_TEST_ASSERT(!sstrcmp(replnotrail, notrailexpect),
   30.93 +            "no trail replacement fails");
   30.94 +    
   30.95 +    UCX_TEST_ASSERT(!sstrcmp(repleq, eqexpect),
   30.96 +            "equal replacement fails");
   30.97 +    
   30.98 +    UCX_TEST_ASSERT(!sstrcmp(replempty1, empty),
   30.99 +            "replacement in empty string fails");
  30.100 +    
  30.101 +    UCX_TEST_ASSERT(!sstrcmp(replempty2, emptyexpect2),
  30.102 +            "empty replacement fails");
  30.103 +    
  30.104 +    UCX_TEST_ASSERT(!sstrcmp(replpre, preexpected),
  30.105 +            "prefix replacement fails");
  30.106 +    
  30.107 +    UCX_TEST_ASSERT(!sstrcmp(replan1, an1expected),
  30.108 +            "a1 replacement fails");
  30.109 +    
  30.110 +    UCX_TEST_ASSERT(!sstrcmp(replan4, an4expected),
  30.111 +            "a4 replacement fails");
  30.112 +    
  30.113 +    UCX_TEST_ASSERT(!sstrcmp(replan9, an9expected),
  30.114 +            "a9 replacement fails");
  30.115 +    
  30.116 +    UCX_TEST_ASSERT(!sstrcmp(replan10, an10expected),
  30.117 +            "a10 replacement fails");
  30.118 +    
  30.119 +    UCX_TEST_ASSERT(!sstrcmp(replcs1, cs1expected),
  30.120 +            "case sensitivity test1 fails");
  30.121 +    
  30.122 +    UCX_TEST_ASSERT(!sstrcmp(replcs2, cs2expected),
  30.123 +            "case sensitivity test2 fails");
  30.124 +
  30.125 +    UCX_TEST_END
  30.126 +
  30.127 +    free(repl.ptr);
  30.128 +    free(repln.ptr);
  30.129 +    free(longrepl.ptr);
  30.130 +    free(replnotrail.ptr);
  30.131 +    free(repleq.ptr);
  30.132 +    if(replempty1.ptr) free(replempty1.ptr);
  30.133 +    free(replempty2.ptr);
  30.134 +    free(replpre.ptr);
  30.135 +    free(replan1.ptr);
  30.136 +    free(replan4.ptr);
  30.137 +    free(replan9.ptr);
  30.138 +    free(replan10.ptr);
  30.139 +    free(replcs1.ptr);
  30.140 +    free(replcs2.ptr);
  30.141 +}
    31.1 --- a/test/string_tests.h	Mon Dec 30 09:52:07 2019 +0100
    31.2 +++ b/test/string_tests.h	Mon Dec 30 09:52:44 2019 +0100
    31.3 @@ -47,6 +47,8 @@
    31.4  UCX_TEST(test_sstrsplit);
    31.5  UCX_TEST(test_sstrtrim);
    31.6  UCX_TEST(test_sstrprefixsuffix);
    31.7 +UCX_TEST(test_sstrcaseprefixsuffix);
    31.8 +UCX_TEST(test_sstrreplace);
    31.9  
   31.10  #ifdef	__cplusplus
   31.11  }

mercurial