diff --git a/CMakeLists.txt b/CMakeLists.txt index 221746e7e..0d90ee04e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,11 +243,11 @@ endif(NATS_BUILD_WITH_TLS) # Versionning and Doc set(NATS_VERSION_MAJOR 3) -set(NATS_VERSION_MINOR 4) -set(NATS_VERSION_PATCH 1) -set(NATS_VERSION_SUFFIX "") +set(NATS_VERSION_MINOR 5) +set(NATS_VERSION_PATCH 0) +set(NATS_VERSION_SUFFIX "-dev") -set(NATS_VERSION_REQUIRED_NUMBER 0x030400) +set(NATS_VERSION_REQUIRED_NUMBER 0x030500) if(NATS_UPDATE_VERSION OR NATS_UPDATE_DOC) configure_file( diff --git a/doc/DoxyFile.NATS.Client b/doc/DoxyFile.NATS.Client index e4a5a272c..7489cf2dc 100644 --- a/doc/DoxyFile.NATS.Client +++ b/doc/DoxyFile.NATS.Client @@ -1,4 +1,4 @@ -# Doxyfile 1.9.5 +# Doxyfile 1.8.10 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,26 +12,16 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). -# -# Note: -# -# Use doxygen to compare the used configuration file with the template -# configuration file: -# doxygen -x [configFile] -# Use doxygen to compare the used configuration file with the template -# configuration file without replacing the environment variables or CMake type -# replacement variables: -# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 @@ -48,7 +38,7 @@ PROJECT_NAME = "NATS C Client with JetStream and Streaming support" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.4.1 +PROJECT_NUMBER = 3.5.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -61,7 +51,7 @@ PROJECT_BRIEF = "The nats.io C Client, Supported by Synadia Communicati # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -70,28 +60,16 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = . -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 -# sub-directories (in 2 levels) under the output directory of each output format -# and will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to -# control the number of sub-directories. +# performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO -# Controls the number of sub-directories that will be created when -# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every -# level increment doubles the number of directories, resulting in 4096 -# directories at level 8 which is the default and also the maximum value. The -# sub-directories are organized in 2 levels, the first level always has a fixed -# numer of 16 directories. -# Minimum value: 0, maximum value: 8, default value: 8. -# This tag requires that the tag CREATE_SUBDIRS is set to YES. - -CREATE_SUBDIRS_LEVEL = 8 - # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -103,14 +81,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, -# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English -# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, -# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with -# English messages), Korean, Korean-en (Korean with English messages), Latvian, -# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, -# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, -# Swedish, Turkish, Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -184,7 +162,7 @@ FULL_PATH_NAMES = NO # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -193,7 +171,7 @@ STRIP_FROM_PATH = # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -211,16 +189,6 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -241,14 +209,6 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -# By default Python docstrings are displayed as preformatted text and doxygen's -# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. -# The default value is: YES. - -PYTHON_DOCSTRING = YES - # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -272,18 +232,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:^^" +# "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". Note that you cannot put \n's in the value part of an alias -# to insert newlines (in the resulting output). You can put ^^ in the value part -# of an alias to insert a newline as if a physical newline was in the original -# file. When you need a literal { or } or , in the value part of an alias you -# have to escape them by means of a backslash (\), this can lead to conflicts -# with the commands \{ and \} for these it is advised to use the version @{ and -# @} or use a double escape (\\{ and \\}) +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. -ALIASES = +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For @@ -313,40 +274,28 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, -# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. When specifying no_extension you should add -# * to the FILE_PATTERNS. -# -# Note see also the list of default file extension mappings. +# the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. +# documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -354,15 +303,6 @@ EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 5 - # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -388,7 +328,7 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -474,19 +414,6 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 -# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of -# cores available in the system. You can set it explicitly to a value larger -# than 0 to get more control over the balance between CPU load and processing -# speed. At this moment only the input processing can be done using multiple -# threads. Since this is still an experimental feature the default is set to 1, -# which effectively disables parallel processing. Please report any issues you -# encounter. Generating dot graphs in parallel is controlled by the -# DOT_NUM_THREADS setting. -# Minimum value: 0, maximum value: 32, default value: 1. - -NUM_PROC_THREADS = 1 - #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -507,12 +434,6 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -550,13 +471,6 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO -# If this flag is set to YES, the name of an unnamed parameter in a declaration -# will be determined by the corresponding definition. By default unnamed -# parameters remain unnamed in the output. -# The default value is: YES. - -RESOLVE_UNNAMED_PARAMS = YES - # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -574,8 +488,8 @@ HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -594,20 +508,12 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# With the correct setting of option CASE_SENSE_NAMES doxygen will better be -# able to match the capabilities of the underlying filesystem. In case the -# filesystem is case sensitive (i.e. it supports files in the same directory -# whose names only differ in casing), the option must be set to YES to properly -# deal with such files in case they appear in the input. For filesystems that -# are not case sensitive the option should be set to NO to properly deal with -# output files written for symbols that only differ in casing, such as for two -# classes, one named CLASS and the other named Class, and to also support -# references to files without having to specify the exact matching casing. On -# Windows (including Cygwin) and MacOS, users should typically set this option -# to NO, whereas on Linux or other Unix flavors it should typically be set to -# YES. -# Possible values are: SYSTEM, NO and YES. -# The default value is: SYSTEM. +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. CASE_SENSE_NAMES = NO @@ -625,12 +531,6 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO -# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class -# will show which file needs to be included to use the class. -# The default value is: YES. - -SHOW_HEADERFILE = YES - # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -688,7 +588,7 @@ SORT_MEMBERS_CTORS_1ST = NO # appear in their defined order. # The default value is: NO. -SORT_GROUP_NAMES = NO +SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will @@ -739,7 +639,7 @@ GENERATE_DEPRECATEDLIST= YES # sections, marked by \if ... \endif and \cond # ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the @@ -781,31 +681,30 @@ SHOW_NAMESPACES = YES # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. See also section "Changing the -# layout of pages" for information. +# will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. -CITE_BIB_FILES = +CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages @@ -835,68 +734,36 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as documenting some parameters in -# a documented function twice, or documenting parameters that don't exist or -# using markup commands wrongly. +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES -# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete -# function parameter documentation. If set to NO, doxygen will accept that some -# parameters have no documentation without warning. -# The default value is: YES. - -WARN_IF_INCOMPLETE_DOC = YES - # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong parameter -# documentation, but not about the absence of documentation. If EXTRACT_ALL is -# set to YES then this flag will automatically be disabled. See also -# WARN_IF_INCOMPLETE_DOC +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS -# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but -# at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. -# The default value is: NO. - -WARN_AS_ERROR = NO - # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) -# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# In the $text part of the WARN_FORMAT command it is possible that a reference -# to a more specific place is given. To make it easier to jump to this place -# (outside of doxygen) the user can define a custom "cut" / "paste" string. -# Example: -# WARN_LINE_FORMAT = "'vi $file +$line'" -# See also: WARN_FORMAT -# The default value is: at line $line of file $file. - -WARN_LINE_FORMAT = "at line $line of file $file" - # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). In case the file specified cannot be opened for writing the -# warning and error messages are written to standard error. When as file - is -# specified the warning and error messages are written to standard output -# (stdout). +# error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -908,29 +775,17 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ../src \ - ../src/adapters +INPUT = ../src ../src/adapters # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: -# https://www.gnu.org/software/libiconv/) for the list of possible encodings. -# See also: INPUT_FILE_ENCODING +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 -# This tag can be used to specify the character encoding of the source files -# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify -# character encoding on a per file pattern basis. Doxygen will compare the file -# name with each pattern and apply the encoding instead of the default -# INPUT_ENCODING) if there is a match. The character encodings are a list of the -# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding -# "INPUT_ENCODING" for further information on supported encodings. - -INPUT_FILE_ENCODING = - # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -939,20 +794,13 @@ INPUT_FILE_ENCODING = # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # -# Note the list of default checked file patterns might differ from the list of -# default file extension mappings. -# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, -# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C -# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf, *.as and *.js. -FILE_PATTERNS = nats.h \ - status.h \ - libevent.h \ - libuv.h +FILE_PATTERNS = nats.h status.h libevent.h libuv.h # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -967,7 +815,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -983,24 +831,24 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# ANamespace::AClass, ANamespace::*Test +# AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -1020,7 +868,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1036,17 +884,8 @@ IMAGE_PATH = # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. -# -# Note that doxygen will use the data processed and written to standard output -# for further processing, therefore nothing else, like debug statements or used -# commands (so in case of a Windows batch file always use @echo OFF), should be -# written to standard output. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. -INPUT_FILTER = +INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the @@ -1054,12 +893,8 @@ INPUT_FILTER = # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. -FILTER_PATTERNS = +FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for @@ -1074,23 +909,14 @@ FILTER_SOURCE_FILES = NO # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. -FILTER_SOURCE_PATTERNS = +FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = - -# The Fortran standard specifies that for fixed formatted Fortran code all -# characters from position 72 are to be considered as comment. A common -# extension is to allow longer lines before the automatic comment starts. The -# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can -# be processed before the automatic comment starts. -# Minimum value: 7, maximum value: 10000, default value: 72. - -FORTRAN_COMMENT_AFTER = 72 +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1119,7 +945,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. +# function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -1151,12 +977,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version +# (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1178,6 +1004,25 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. + +#CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +#CLANG_OPTIONS = + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1189,13 +1034,20 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -1274,7 +1126,7 @@ HTML_STYLESHEET = customdoxygen.css # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1284,29 +1136,12 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output -# should be rendered with a dark or light theme. Default setting AUTO_LIGHT -# enables light output unless the user preference is dark output. Other options -# are DARK to always use dark mode, LIGHT to always use light mode, AUTO_DARK to -# default to dark mode unless the user prefers light mode, and TOGGLE to let the -# user toggle between dark and light mode via a button. -# Possible values are: LIGHT Always generate light output., DARK Always generate -# dark output., AUTO_LIGHT Automatically set the mode according to the user -# preference, use light mode if no preference is set (the default)., AUTO_DARK -# Automatically set the mode according to the user preference, use dark mode if -# no preference is set. and TOGGLE Allow to user to switch between light and -# dark mode via a button.. -# The default value is: AUTO_LIGHT. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE = AUTO_LIGHT +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a color-wheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. @@ -1315,7 +1150,7 @@ HTML_COLORSTYLE = AUTO_LIGHT HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use gray-scales only. A +# in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1342,17 +1177,6 @@ HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. @@ -1376,14 +1200,13 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: -# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To -# create a documentation set, doxygen will generate a Makefile in the HTML -# output directory. Running make will produce the docset in that directory and -# running make install will install the docset in +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1397,13 +1220,6 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" -# This tag determines the URL of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDURL = - # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1429,12 +1245,8 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# on Windows. In the beginning of 2021 Microsoft took the original page, with -# a.o. the download links, offline the HTML help workshop was already many years -# in maintenance mode). You can download the HTML help workshop from the web -# archives at Installation executable (see: -# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo -# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1453,7 +1265,7 @@ GENERATE_HTMLHELP = NO # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_FILE = +CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, @@ -1461,10 +1273,10 @@ CHM_FILE = # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -HHC_LOCATION = +HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the main .chm file (NO). +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1474,7 +1286,7 @@ GENERATE_CHI = NO # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it @@ -1505,12 +1317,11 @@ GENERATE_QHP = NO # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. -QCH_FILE = +QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1518,8 +1329,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1527,33 +1338,33 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location (absolute path -# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to -# run qhelpgenerator on the generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. -QHG_LOCATION = +QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To @@ -1593,28 +1404,16 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine tune the look of the index (see "Fine-tuning the output"). As an -# example, the default style sheet generated by doxygen has an example that -# shows how to put an image at the root of the tree instead of the PROJECT_NAME. -# Since the tree basically has the same information as the tab index, you could -# consider setting DISABLE_INDEX to YES when enabling this option. +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES -# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the -# FULL_SIDEBAR option determines if the side bar is limited to only the treeview -# area (value NO) or if it should extend to the full height of the window (value -# YES). Setting this to YES gives a layout similar to -# https://docs.readthedocs.io with more room for contents, but less room for the -# project logo, title, and description. If either GENERATE_TREEVIEW or -# DISABLE_INDEX is set to NO, this option has no effect. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FULL_SIDEBAR = NO - # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1639,24 +1438,6 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO -# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email -# addresses. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -OBFUSCATE_EMAILS = YES - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png (the default) and svg (looks nicer but requires the -# pdf2svg or inkscape tool). -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1666,14 +1447,19 @@ HTML_FORMULA_FORMAT = png FORMULA_FONTSIZE = 10 -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. -FORMULA_MACROFILE = +FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering +# http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1683,29 +1469,11 @@ FORMULA_MACROFILE = USE_MATHJAX = NO -# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. -# Note that the different versions of MathJax have different requirements with -# regards to the different settings, so it is possible that also other MathJax -# settings have to be changed when switching between the different MathJax -# versions. -# Possible values are: MathJax_2 and MathJax_3. -# The default value is: MathJax_2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_VERSION = MathJax_2 - # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. For more details about the output format see MathJax -# version 2 (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 -# (see: -# http://docs.mathjax.org/en/latest/web/components/output.html). +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility. This is the name for Mathjax version 2, for MathJax version 3 -# this will be translated into chtml), NativeMML (i.e. MathML. Only supported -# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This -# is the name for Mathjax version 3, for MathJax version 2 this will be -# translated into HTML-CSS) and SVG. +# compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1718,33 +1486,26 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. The default value is: -# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 -# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example -# for MathJax version 2 (see -# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# For example for MathJax version 3 (see -# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): -# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_CODEFILE = +MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and @@ -1768,7 +1529,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using JavaScript. There +# implemented using a web server instead of a web client using Javascript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1787,8 +1548,7 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: -# https://xapian.org/). +# Xapian (see: http://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1801,12 +1561,11 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: -# https://xapian.org/). See the section "External Indexing and Searching" for -# details. +# Xapian (see: http://xapian.org/). See the section "External Indexing and +# Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. -SEARCHENGINE_URL = +SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the @@ -1822,7 +1581,7 @@ SEARCHDATA_FILE = searchdata.xml # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. -EXTERNAL_SEARCH_ID = +EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are @@ -1832,7 +1591,7 @@ EXTERNAL_SEARCH_ID = # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. -EXTRA_SEARCH_MAPPINGS = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output @@ -1849,40 +1608,26 @@ GENERATE_LATEX = NO # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_OUTPUT = +LATEX_OUTPUT = # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when not enabling USE_PDFLATEX the default is latex when enabling -# USE_PDFLATEX the default is pdflatex and when in the later case latex is -# chosen this is overwritten by pdflatex. For specific output languages the -# default can have been set differently, this depends on the implementation of -# the output language. +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. -# Note: This tag is used in the Makefile / make.bat. -# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file -# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex -# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to -# generate index for LaTeX. In case there is no backslash (\) as first character -# it will be automatically added in the LaTeX code. -# Note: This tag is used in the generated output file (.tex). -# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. -# The default value is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_MAKEINDEX_CMD = makeindex - # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1910,36 +1655,34 @@ PAPER_TYPE = a4 # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for -# the generated LaTeX document. The header should contain everything until the -# first chapter. If it is left blank doxygen will generate a standard header. It -# is highly recommended to start with a default header using -# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty -# and then modify the file new_header.tex. See also section "Doxygen usage" for -# information on how to generate the default header that doxygen normally uses. +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. # -# Note: Only use a user-defined header if you know what you are doing! -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. The following -# commands have a special meaning inside the header (and footer): For a -# description of the possible markers and block names see the documentation. +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_HEADER = +LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for -# the generated LaTeX document. The footer should contain everything after the -# last chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. See also section "Doxygen -# usage" for information on how to generate the default footer that doxygen -# normally uses. Note: Only use a user-defined footer if you know what you are -# doing! +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_FOOTER = +LATEX_FOOTER = # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined # LaTeX style sheets that are included after the standard style sheets created @@ -1950,7 +1693,7 @@ LATEX_FOOTER = # list). # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_STYLESHEET = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output @@ -1958,7 +1701,7 @@ LATEX_EXTRA_STYLESHEET = # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_FILES = +LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will @@ -1969,11 +1712,9 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as -# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX -# files. Set this option to YES, to get a higher quality PDF documentation. -# -# See also section LATEX_CMD_NAME for selecting the engine. +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1981,7 +1722,8 @@ USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1994,29 +1736,23 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. See -# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BIB_STYLE = plain - -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_TIMESTAMP = NO +LATEX_SOURCE_CODE = NO -# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) -# path from which the emoji images will be read. If a relative path is entered, -# it will be relative to the LATEX_OUTPUT directory. If left blank the -# LATEX_OUTPUT directory will be used. +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EMOJI_DIRECTORY = +LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -2057,22 +1793,32 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# configuration file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's configuration file. A template extensions file can be -# generated using doxygen -e rtf extensionFile. +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- # Configuration options related to the man page output @@ -2107,7 +1853,7 @@ MAN_EXTENSION = .3 # MAN_EXTENSION with the initial . removed. # This tag requires that the tag GENERATE_MAN is set to YES. -MAN_SUBDIR = +MAN_SUBDIR = # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real @@ -2145,13 +1891,6 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES -# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include -# namespace members in file scope as well, matching the HTML output. -# The default value is: NO. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_NS_MEMB_FILE_SCOPE = NO - #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -2170,14 +1909,23 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures -# the structure of the code including all documentation. Note that this feature -# is still experimental and incomplete at the moment. +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -2218,7 +1966,7 @@ PERLMOD_PRETTY = YES # overwrite each other's variables. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor @@ -2256,11 +2004,10 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of -# RECURSIVE has no effect here. +# preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2268,7 +2015,7 @@ INCLUDE_PATH = # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -2278,8 +2025,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = BUILD_IN_DOXYGEN \ - NATS_HAS_STREAMING +PREDEFINED = BUILD_IN_DOXYGEN NATS_HAS_STREAMING # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2288,7 +2034,7 @@ PREDEFINED = BUILD_IN_DOXYGEN \ # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2317,13 +2063,13 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be @@ -2346,16 +2092,40 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. -DIA_PATH = +DIA_PATH = # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. @@ -2382,50 +2152,35 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of -# subgraphs. When you want a differently looking font in the dot files that -# doxygen generates you can specify fontname, fontcolor and fontsize attributes. -# For details please see Node, -# Edge and Graph Attributes specification You need to make sure dot is able -# to find the font, which can be done by putting it in a standard location or by -# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. Default graphviz fontsize is 14. -# The default value is: fontname=Helvetica,fontsize=10. +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" +DOT_FONTNAME = Helvetica -# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can -# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about -# arrows shapes. -# The default value is: labelfontname=Helvetica,labelfontsize=10. +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" +DOT_FONTSIZE = 10 -# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes -# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification -# The default value is: shape=box,height=0.2,width=0.4. +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" +DOT_FONTPATH = -# You can set the path where dot can find font specified with fontname in -# DOT_COMMON_ATTR and others dot attributes. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTPATH = - -# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a -# graph for each documented class showing the direct and indirect inheritance -# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, -# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set -# to TEXT the direct and indirect inheritance relations will be shown as texts / -# links. -# Possible values are: NO, YES, TEXT and GRAPH. +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. # The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2439,8 +2194,7 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. See also the chapter Grouping -# in the manual. +# groups, showing the direct groups dependencies. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2463,31 +2217,9 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag UML_LOOK is set to YES. - -UML_LIMIT_NUM_FIELDS = 10 - -# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and -# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS -# tag is set to YES, doxygen will add type and arguments for attributes and -# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen -# will not generate fields with class member information in the UML graphs. The -# class diagrams will look similar to the default class diagrams but using UML -# notation for the relationships. -# Possible values are: NO, YES and NONE. -# The default value is: NO. -# This tag requires that the tag UML_LOOK is set to YES. - -DOT_UML_DETAILS = NO - -# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters -# to display on a single line. If the actual line length exceeds this threshold -# significantly it will wrapped across multiple lines. Some heuristics are apply -# to avoid ugly line breaks. -# Minimum value: 0, maximum value: 1000, default value: 17. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_WRAP_THRESHOLD = 17 +UML_LIMIT_NUM_FIELDS = 10 # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their @@ -2555,13 +2287,6 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES -# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels -# of child directories generated in directory dependency graphs by dot. -# Minimum value: 1, maximum value: 25, default value: 1. -# This tag requires that the tag DIRECTORY_GRAPH is set to YES. - -DIR_GRAPH_MAX_DEPTH = 1 - # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: @@ -2593,44 +2318,39 @@ INTERACTIVE_SVG = NO # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = +DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile # command). # This tag requires that the tag HAVE_DOT is set to YES. -DOTFILE_DIRS = +DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). -MSCFILE_DIRS = +MSCFILE_DIRS = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile # command). -DIAFILE_DIRS = +DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file or to the filename of jar file -# to be used. If left blank, it is assumed PlantUML is not used or called during -# a preprocessing step. Doxygen will generate a warning when it encounters a -# \startuml command in this case and will not generate output for the diagram. - -PLANTUML_JAR_PATH = +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. -# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a -# configuration file for plantuml. - -PLANTUML_CFG_FILE = +PLANTUML_JAR_PATH = # When using plantuml, the specified paths are searched for files specified by # the !include statement in a plantuml block. -PLANTUML_INCLUDE_PATH = +PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes @@ -2656,6 +2376,18 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2668,18 +2400,14 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. -# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal -# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. -# -# Note: This setting is not only used for dot files but also for msc temporary -# files. # The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES diff --git a/src/js.h b/src/js.h index 8f0f26044..79ce521cd 100644 --- a/src/js.h +++ b/src/js.h @@ -103,6 +103,9 @@ extern const int64_t jsDefaultRequestWait; #define jsAckInProgress "+WPI" #define jsAckTerm "+TERM" +// jsExtDomainT is used to create a StreamSource External APIPrefix +#define jsExtDomainT "$JS.%s.API" + // jsApiAccountInfo is for obtaining general information about JetStream. #define jsApiAccountInfo "%.*s.INFO" diff --git a/src/jsm.c b/src/jsm.c index 1fd25db59..2a5d5b73d 100644 --- a/src/jsm.c +++ b/src/jsm.c @@ -211,6 +211,18 @@ js_cleanStreamState(jsStreamState *state) _destroyStreamStateSubjects(state->Subjects); } +static void +_destroyStreamAlternate(jsStreamAlternate *sa) +{ + if (sa == NULL) + return; + + NATS_FREE((char*) sa->Name); + NATS_FREE((char*) sa->Domain); + NATS_FREE((char*) sa->Cluster); + NATS_FREE(sa); +} + void jsStreamInfo_Destroy(jsStreamInfo *si) { @@ -226,6 +238,9 @@ jsStreamInfo_Destroy(jsStreamInfo *si) for (i=0; iSourcesLen; i++) _destroyStreamSourceInfo(si->Sources[i]); NATS_FREE(si->Sources); + for (i=0; iAlternatesLen; i++) + _destroyStreamAlternate(si->Alternates[i]); + NATS_FREE(si->Alternates); NATS_FREE(si); } @@ -264,8 +279,11 @@ _marshalExternalStream(jsExternalStream *external, const char *fieldName, natsBu IFOK(s, natsBuf_Append(buf, fieldName, -1)); IFOK(s, natsBuf_Append(buf, "\":{\"api\":\"", -1)); IFOK(s, natsBuf_Append(buf, external->APIPrefix, -1)); - IFOK(s, natsBuf_Append(buf, "\",\"deliver\":\"", -1)); - IFOK(s, natsBuf_Append(buf, external->DeliverPrefix, -1)); + if ((s == NATS_OK) && !nats_IsStringEmpty(external->DeliverPrefix)) + { + IFOK(s, natsBuf_Append(buf, "\",\"deliver\":\"", -1)); + IFOK(s, natsBuf_Append(buf, external->DeliverPrefix, -1)); + } IFOK(s, natsBuf_Append(buf, "\"}", -1)); return NATS_UPDATE_ERR_STACK(s); @@ -952,12 +970,36 @@ _unmarshalStreamSourceInfo(nats_JSON *pjson, const char *fieldName, jsStreamSour return NATS_UPDATE_ERR_STACK(s); } +static natsStatus +_unmarshalStreamAlternate(nats_JSON *json, jsStreamAlternate **new_alt) +{ + jsStreamAlternate *sa = NULL; + natsStatus s = NATS_OK; + + sa = (jsStreamAlternate*) NATS_CALLOC(1, sizeof(jsStreamAlternate)); + if (sa == NULL) + return nats_setDefaultError(NATS_NO_MEMORY); + + s = nats_JSONGetStr(json, "name", (char**) &(sa->Name)); + IFOK(s, nats_JSONGetStr(json, "domain", (char**) &(sa->Domain))); + IFOK(s, nats_JSONGetStr(json, "cluster", (char**) &(sa->Cluster))); + + if (s == NATS_OK) + *new_alt = sa; + else + _destroyStreamAlternate(sa); + + return NATS_UPDATE_ERR_STACK(s); +} + static natsStatus _unmarshalStreamInfoPaged(nats_JSON *json, jsStreamInfo **new_si, apiPaged *page) { jsStreamInfo *si = NULL; nats_JSON **sources = NULL; int sourcesLen = 0; + nats_JSON **alts = NULL; + int altsLen = 0; natsStatus s; si = (jsStreamInfo*) NATS_CALLOC(1, sizeof(jsStreamInfo)); @@ -988,6 +1030,24 @@ _unmarshalStreamInfoPaged(nats_JSON *json, jsStreamInfo **new_si, apiPaged *page // Free the array of JSON objects that was allocated by nats_JSONGetArrayObject. NATS_FREE(sources); } + IFOK(s, nats_JSONGetArrayObject(json, "alternates", &alts, &altsLen)); + if ((s == NATS_OK) && (alts != NULL)) + { + int i; + + si->Alternates = (jsStreamAlternate**) NATS_CALLOC(altsLen, sizeof(jsStreamAlternate*)); + if (si->Alternates == NULL) + s = nats_setDefaultError(NATS_NO_MEMORY); + + for (i=0; (s == NATS_OK) && (iAlternates[i])); + if (s == NATS_OK) + si->AlternatesLen++; + } + // Free the array of JSON objects that was allocated by nats_JSONGetArrayObject. + NATS_FREE(alts); + } if ((s == NATS_OK) && (page != NULL)) { IFOK(s, nats_JSONGetLong(json, "total", &page->total)); @@ -1061,6 +1121,95 @@ jsStreamConfig_Init(jsStreamConfig *cfg) return NATS_OK; } +static void +_restoreMirrorAndSourcesExternal(jsStreamConfig *cfg) +{ + int i; + + // We are guaranteed that if a source's Domain is set, there was originally + // no External value. So free any External value and reset to NULL to + // restore the original setting. + if ((cfg->Mirror != NULL) && !nats_IsStringEmpty(cfg->Mirror->Domain)) + { + _destroyExternalStream(cfg->Mirror->External); + cfg->Mirror->External = NULL; + } + for (i=0; iSourcesLen; i++) + { + jsStreamSource *src = cfg->Sources[i]; + if ((src != NULL) && !nats_IsStringEmpty(src->Domain)) + { + _destroyExternalStream(src->External); + src->External = NULL; + } + } +} + +static natsStatus +_convertDomain(jsStreamSource *src) +{ + jsExternalStream *e = NULL; + + e = (jsExternalStream*) NATS_CALLOC(1, sizeof(jsExternalStream)); + if (e == NULL) + return nats_setDefaultError(NATS_NO_MEMORY); + + if (nats_asprintf((char**) &(e->APIPrefix), jsExtDomainT, src->Domain) < 0) + { + NATS_FREE(e); + return nats_setDefaultError(NATS_NO_MEMORY); + } + src->External = e; + return NATS_OK; +} + +static natsStatus +_convertMirrorAndSourcesDomain(bool *converted, jsStreamConfig *cfg) +{ + natsStatus s = NATS_OK; + bool cm = false; + bool cs = false; + int i; + + *converted = false; + + if ((cfg->Mirror != NULL) && !nats_IsStringEmpty(cfg->Mirror->Domain)) + { + if (cfg->Mirror->External != NULL) + return nats_setError(NATS_INVALID_ARG, "%s", "mirror's domain and external are both set"); + cm = true; + } + for (i=0; iSourcesLen; i++) + { + jsStreamSource *src = cfg->Sources[i]; + if ((src != NULL) && !nats_IsStringEmpty(src->Domain)) + { + if (src->External != NULL) + return nats_setError(NATS_INVALID_ARG, "%s", "source's domain and external are both set"); + cs = true; + } + } + if (!cm && !cs) + return NATS_OK; + + if (cm) + s = _convertDomain(cfg->Mirror); + if ((s == NATS_OK) && cs) + { + for (i=0; (s == NATS_OK) && (iSourcesLen); i++) + { + jsStreamSource *src = cfg->Sources[i]; + if ((src != NULL) && !nats_IsStringEmpty(src->Domain)) + s = _convertDomain(src); + } + } + if (s == NATS_OK) + *converted = true; + else + _restoreMirrorAndSourcesExternal(cfg); + return NATS_UPDATE_ERR_STACK(s); +} + static natsStatus _addOrUpdate(jsStreamInfo **new_si, jsStreamAction action, jsCtx *js, jsStreamConfig *cfg, jsOptions *opts, jsErrCode *errCode) { @@ -1071,6 +1220,7 @@ _addOrUpdate(jsStreamInfo **new_si, jsStreamAction action, jsCtx *js, jsStreamCo natsConnection *nc = NULL; const char *apiT = NULL; bool freePfx = false; + bool msc = false; jsOptions o; if (errCode != NULL) @@ -1101,6 +1251,8 @@ _addOrUpdate(jsStreamInfo **new_si, jsStreamAction action, jsCtx *js, jsStreamCo if (freePfx) NATS_FREE((char*) o.Prefix); } + if ((s == NATS_OK) && (action == jsStreamActionCreate)) + s = _convertMirrorAndSourcesDomain(&msc, cfg); // Marshal the stream create/update request IFOK(s, js_marshalStreamConfig(&buf, cfg)); @@ -1111,6 +1263,12 @@ _addOrUpdate(jsStreamInfo **new_si, jsStreamAction action, jsCtx *js, jsStreamCo // If we got a response, check for error or return the stream info result. IFOK(s, _unmarshalStreamCreateResp(new_si, NULL, resp, errCode)); + // If mirror and/or sources were converted for the domain, then we need + // to restore the original values (which will free the memory that was + // allocated for the conversion). + if (msc) + _restoreMirrorAndSourcesExternal(cfg); + natsBuf_Destroy(buf); natsMsg_Destroy(resp); NATS_FREE(subj); diff --git a/src/kv.c b/src/kv.c index 38539f2ff..a82826876 100644 --- a/src/kv.c +++ b/src/kv.c @@ -21,9 +21,11 @@ #include "conn.h" #include "sub.h" -static const char *kvBucketNameTmpl = "KV_%s"; -static const char *kvSubjectsTmpl = "$KV.%s.>"; -static const char *kvSubjectsPreTmpl = "$KV.%s."; +static const char *kvBucketNamePre = "KV_"; +static const char *kvBucketNameTmpl = "KV_%s"; +static const char *kvSubjectsTmpl = "$KV.%s.>"; +static const char *kvSubjectsPreTmpl = "$KV.%s."; +static const char *kvSubjectsPreDomainTmpl = "%s.$KV.%s."; #define KV_WATCH_FOR_EVER (int64_t)(0x7FFFFFFFFFFFFFFF) @@ -34,14 +36,17 @@ natsBuffer buf; #define USE_JS_PREFIX true #define KEY_NAME_ONLY false -#define BUILD_SUBJECT(p) \ +#define FOR_A_PUT true +#define NOT_FOR_A_PUT false + +#define BUILD_SUBJECT(p, fp) \ s = natsBuf_InitWithBackend(&buf, buffer, 0, sizeof(buffer)); \ if ((p) && kv->useJSPrefix) \ { \ IFOK(s, natsBuf_Append(&buf, kv->js->opts.Prefix, -1)); \ IFOK(s, natsBuf_AppendByte(&buf, '.')); \ } \ -IFOK(s, natsBuf_Append(&buf, kv->pre, -1)); \ +IFOK(s, natsBuf_Append(&buf, ((fp) ? (kv->usePutPre ? kv->putPre : kv->pre) : kv->pre), -1)); \ IFOK(s, natsBuf_Append(&buf, key, -1)); \ IFOK(s, natsBuf_AppendByte(&buf, 0)); @@ -119,6 +124,7 @@ _freeKV(kvStore *kv) NATS_FREE(kv->bucket); NATS_FREE(kv->stream); NATS_FREE(kv->pre); + NATS_FREE(kv->putPre); natsMutex_Destroy(kv->mu); NATS_FREE(kv); js_release(js); @@ -188,52 +194,38 @@ _createKV(kvStore **new_kv, jsCtx *js, const char *bucket) return NATS_UPDATE_ERR_STACK(s); } -static bool -_sameStrings(const char *s1, const char *s2) +static natsStatus +_changePutPrefixIfMirrorPresent(kvStore *kv, jsStreamInfo *si) { - bool s1Empty = nats_IsStringEmpty(s1); - bool s2Empty = nats_IsStringEmpty(s2); + natsStatus s = NATS_OK; + const char *bucket = NULL; + jsStreamSource *m = si->Config->Mirror; - // Same if both empty. - if (s1Empty && s2Empty) - return true; + if (m == NULL) + return NATS_OK; - // Not same if one is empty while other is not. - if ((s1Empty && !s2Empty) || (!s1Empty && s2Empty)) - return false; + bucket = m->Name; + if (strstr(m->Name, kvBucketNamePre) == m->Name) + bucket = m->Name + strlen(kvBucketNamePre); - // Return result of comparison of s1 and s2 - return (strcmp(s1, s2) == 0 ? true : false); -} + if ((m->External != NULL) && !nats_IsStringEmpty(m->External->APIPrefix)) + { + kv->useJSPrefix = false; -static bool -_sameStreamCfg(jsStreamConfig *oc, jsStreamConfig *nc) -{ - // Check some of the stream's configuration properties only, - // the ones that we set when creating a KV stream. - if (!_sameStrings(oc->Description, nc->Description)) - return false; - if (oc->SubjectsLen != nc->SubjectsLen) - return false; - if (!_sameStrings(oc->Subjects[0], nc->Subjects[0])) - return false; - if (oc->MaxMsgsPerSubject != nc->MaxMsgsPerSubject) - return false; - if (oc->MaxBytes != nc->MaxBytes) - return false; - if (oc->MaxAge != nc->MaxAge) - return false; - if (oc->MaxMsgSize != nc->MaxMsgSize) - return false; - if (oc->Storage != nc->Storage) - return false; - if (oc->Replicas != nc->Replicas) - return false; - if (oc->AllowRollup != nc->AllowRollup) - return false; - if (oc->DenyDelete != nc->DenyDelete) - return false; - return true; + NATS_FREE(kv->pre); + kv->pre = NULL; + if (nats_asprintf(&(kv->pre), kvSubjectsPreTmpl, bucket) < 0) + s = nats_setDefaultError(NATS_NO_MEMORY); + else if (nats_asprintf(&(kv->putPre), kvSubjectsPreDomainTmpl, m->External->APIPrefix, bucket) < 0) + s = nats_setDefaultError(NATS_NO_MEMORY); + } + else if (nats_asprintf(&(kv->putPre), kvSubjectsPreTmpl, bucket) < 0) + s = nats_setDefaultError(NATS_NO_MEMORY); + + if (s == NATS_OK) + kv->usePutPre = true; + + return NATS_UPDATE_ERR_STACK(s); } natsStatus @@ -245,6 +237,8 @@ js_CreateKeyValue(kvStore **new_kv, jsCtx *js, kvConfig *cfg) kvStore *kv = NULL; char *subject= NULL; jsStreamInfo *si = NULL; + const char *omn = NULL; + const char **osn = NULL; jsStreamConfig sc; if ((new_kv == NULL) || (js == NULL) || (cfg == NULL)) @@ -274,12 +268,11 @@ js_CreateKeyValue(kvStore **new_kv, jsCtx *js, kvConfig *cfg) int64_t maxBytes = (cfg->MaxBytes == 0 ? -1 : cfg->MaxBytes); int32_t maxMsgSize = (cfg->MaxValueSize == 0 ? -1 : cfg->MaxValueSize); jsErrCode jerr = 0; + const char **subjects = (const char*[1]){subject}; jsStreamConfig_Init(&sc); sc.Name = kv->stream; sc.Description = cfg->Description; - sc.Subjects = (const char*[1]){subject}; - sc.SubjectsLen = 1; sc.MaxMsgsPerSubject = history; sc.MaxBytes = maxBytes; sc.MaxAge = cfg->TTL; @@ -291,38 +284,106 @@ js_CreateKeyValue(kvStore **new_kv, jsCtx *js, kvConfig *cfg) sc.AllowDirect = true; sc.RePublish = cfg->RePublish; - // If connecting to a v2.7.2+, create with discard new policy - if (natsConn_srvVersionAtLeast(kv->js->nc, 2, 7, 2)) - sc.Discard = js_DiscardNew; + if (cfg->Mirror != NULL) + { + jsStreamSource *m = cfg->Mirror; - s = js_AddStream(&si, js, &sc, NULL, &jerr); - if ((s != NATS_OK) && (jerr == JSStreamNameExistErr)) + if (!nats_IsStringEmpty(m->Name) + && (strstr(m->Name, kvBucketNamePre) != m->Name)) + { + char *newName = NULL; + if (nats_asprintf(&newName, kvBucketNameTmpl, m->Name) < 0) + s = nats_setDefaultError(NATS_NO_MEMORY); + else + { + omn = m->Name; + m->Name = newName; + } + } + sc.Mirror = m; + sc.MirrorDirect = true; + } + else if (cfg->SourcesLen > 0) { - jsStreamInfo_Destroy(si); - si = NULL; + osn = (const char**) NATS_CALLOC(cfg->SourcesLen, sizeof(char*)); + if (osn == NULL) + s = nats_setDefaultError(NATS_NO_MEMORY); - nats_clearLastError(); - s = js_GetStreamInfo(&si, js, sc.Name, NULL, NULL); if (s == NATS_OK) { - si->Config->Discard = sc.Discard; - if (_sameStreamCfg(si->Config, &sc)) + int i; + + for (i=0; iSourcesLen; i++) { - jsStreamInfo_Destroy(si); - si = NULL; - s = js_UpdateStream(&si, js, &sc, NULL, NULL); + jsStreamSource *ss = cfg->Sources[i]; + + if (ss == NULL) + continue; + + // Set this regardless of error in the loop. We need it for + // proper cleanup at the end. + osn[i] = ss->Name; + + if ((s == NATS_OK) && !nats_IsStringEmpty(ss->Name) + && (strstr(ss->Name, kvBucketNamePre) != ss->Name)) + { + char *newName = NULL; + + if (nats_asprintf(&newName, kvBucketNameTmpl, ss->Name) < 0) + s = nats_setDefaultError(NATS_NO_MEMORY); + else + ss->Name = newName; + } + } + if (s == NATS_OK) + { + sc.Sources = cfg->Sources; + sc.SourcesLen = cfg->SourcesLen; } - else - s = nats_setError(NATS_ERR, "%s", - "Existing configuration is different"); } } + else + { + sc.Subjects = subjects; + sc.SubjectsLen = 1; + } + + // If connecting to a v2.7.2+, create with discard new policy + if (natsConn_srvVersionAtLeast(kv->js->nc, 2, 7, 2)) + sc.Discard = js_DiscardNew; + + s = js_AddStream(&si, js, &sc, NULL, &jerr); if (s == NATS_OK) { // If the stream allow direct get message calls, then we will do so. kv->useDirect = si->Config->AllowDirect; + + s = _changePutPrefixIfMirrorPresent(kv, si); } jsStreamInfo_Destroy(si); + + // Restore original mirror/source names + if (omn != NULL) + { + NATS_FREE((char*) cfg->Mirror->Name); + cfg->Mirror->Name = omn; + } + if (osn != NULL) + { + int i; + + for (i=0; iSourcesLen; i++) + { + jsStreamSource *ss = cfg->Sources[i]; + + if ((ss != NULL) && (ss->Name != osn[i])) + { + NATS_FREE((char*) ss->Name); + ss->Name = osn[i]; + } + } + NATS_FREE((char**) osn); + } } if (s == NATS_OK) *new_kv = kv; @@ -359,6 +420,8 @@ js_KeyValue(kvStore **new_kv, jsCtx *js, const char *bucket) if (si->Config->MaxMsgsPerSubject < 1) s = nats_setError(NATS_INVALID_ARG, "%s", kvErrBadBucket); + IFOK(s, _changePutPrefixIfMirrorPresent(kv, si)); + jsStreamInfo_Destroy(si); } @@ -480,7 +543,7 @@ _getEntry(kvEntry **new_entry, bool *deleted, kvStore *kv, const char *key, uint if (!validKey(key)) return nats_setError(NATS_INVALID_ARG, "%s", kvErrInvalidKey); - BUILD_SUBJECT(KEY_NAME_ONLY); + BUILD_SUBJECT(KEY_NAME_ONLY, NOT_FOR_A_PUT); if (kv->useDirect) { @@ -600,7 +663,7 @@ _putEntry(uint64_t *rev, kvStore *kv, jsPubOptions *po, const char *key, const v if (!validKey(key)) return nats_setError(NATS_INVALID_ARG, "%s", kvErrInvalidKey); - BUILD_SUBJECT(USE_JS_PREFIX); + BUILD_SUBJECT(USE_JS_PREFIX, FOR_A_PUT); IFOK(s, js_Publish(ppa, kv->js, natsBuf_Data(&buf), data, len, po, NULL)); if ((s == NATS_OK) && (rev != NULL)) @@ -703,7 +766,7 @@ _delete(kvStore *kv, const char *key, bool purge, kvPurgeOptions *opts) if (!validKey(key)) return nats_setError(NATS_INVALID_ARG, "%s", kvErrInvalidKey); - BUILD_SUBJECT(USE_JS_PREFIX); + BUILD_SUBJECT(USE_JS_PREFIX, FOR_A_PUT); IFOK(s, natsMsg_Create(&msg, natsBuf_Data(&buf), NULL, NULL, 0)); if (s == NATS_OK) { @@ -816,6 +879,7 @@ kvStore_PurgeDeletes(kvStore *kv, kvPurgeOptions *opts) for (; h != NULL; ) { natsBuf_Reset(&buf); + // Use kv->pre here, always. IFOK(s, natsBuf_Append(&buf, kv->pre, -1)); IFOK(s, natsBuf_Append(&buf, h->key, -1)); IFOK(s, natsBuf_AppendByte(&buf, '\0')); @@ -922,6 +986,7 @@ kvWatcher_Next(kvEntry **new_entry, kvWatcher *w, int64_t timeout) } w->refs--; + // Use kv->pre here, always. if ((s == NATS_OK) && (strlen(msg->subject) <= strlen(w->kv->pre))) s = nats_setError(NATS_ERR, "invalid update's subject '%s'", msg->subject); @@ -1011,7 +1076,7 @@ kvStore_Watch(kvWatcher **new_watcher, kvStore *kv, const char *key, kvWatchOpti w->kv = kv; w->refs = 1; - BUILD_SUBJECT(KEY_NAME_ONLY); + BUILD_SUBJECT(KEY_NAME_ONLY, NOT_FOR_A_PUT); IFOK(s, natsMutex_Create(&(w->mu))); if (s == NATS_OK) { @@ -1028,6 +1093,9 @@ kvStore_Watch(kvWatcher **new_watcher, kvStore *kv, const char *key, kvWatchOpti if (opts->IgnoreDeletes) w->ignoreDel = true; } + // Need to explicitly bind to the stream here because the subject + // we construct may not help find the stream when using mirrors. + so.Stream = kv->stream; s = js_SubscribeSync(&(w->sub), kv->js, natsBuf_Data(&buf), NULL, &so, NULL); IFOK(s, natsSubscription_SetPendingLimits(w->sub, -1, -1)); if (s == NATS_OK) @@ -1312,6 +1380,12 @@ kvStatus_Replicas(kvStatus *sts) return (sts == NULL || sts->si->Config == NULL ? 0 : sts->si->Config->Replicas); } +uint64_t +kvStatus_Bytes(kvStatus *sts) +{ + return (sts == NULL ? 0 : sts->si->State.Bytes); +} + void kvStatus_Destroy(kvStatus *sts) { diff --git a/src/nats.h b/src/nats.h index 2e046ace9..ca3bab9ec 100644 --- a/src/nats.h +++ b/src/nats.h @@ -375,6 +375,10 @@ typedef struct jsStreamSource int64_t OptStartTime; ///< UTC time expressed as number of nanoseconds since epoch. const char *FilterSubject; jsExternalStream *External; + // Domain and External are mutually exclusive. + // If Domain is set, an External value will be created with + // the APIPrefix constructed based on the Domain value. + const char *Domain; } jsStreamSource; @@ -631,6 +635,17 @@ typedef struct jsStreamSourceInfo } jsStreamSourceInfo; +/** + * Information about an alternate stream represented by a mirror. + */ +typedef struct jsStreamAlternate +{ + const char *Name; + const char *Domain; + const char *Cluster; + +} jsStreamAlternate; + /** * Configuration and current state for this stream. * @@ -646,6 +661,8 @@ typedef struct jsStreamInfo jsStreamSourceInfo *Mirror; jsStreamSourceInfo **Sources; int SourcesLen; + jsStreamAlternate **Alternates; + int AlternatesLen; } jsStreamInfo; @@ -1189,6 +1206,9 @@ typedef struct kvConfig jsStorageType StorageType; int Replicas; jsRePublish *RePublish; + jsStreamSource *Mirror; + jsStreamSource **Sources; + int SourcesLen; } kvConfig; @@ -7028,6 +7048,15 @@ kvStatus_TTL(kvStatus *sts); NATS_EXTERN int64_t kvStatus_Replicas(kvStatus *sts); +/** \brief Returns the size (in bytes) of this bucket. + * + * Returns the size (in bytes) of this bucket, or `0` if `sts` itself is `NULL`. + * + * @param sts the pointer to the #kvStatus object. + */ +NATS_EXTERN uint64_t +kvStatus_Bytes(kvStatus *sts); + /** \brief Destroys the KeyValue status object. * * Releases memory allocated for this #kvStatus object. diff --git a/src/natsp.h b/src/natsp.h index 8385e4844..fb6dde262 100644 --- a/src/natsp.h +++ b/src/natsp.h @@ -433,6 +433,8 @@ struct __kvStore char *bucket; char *stream; char *pre; + char *putPre; + bool usePutPre; bool useJSPrefix; bool useDirect; diff --git a/src/status.h b/src/status.h index 729d52f01..ee8bfe703 100644 --- a/src/status.h +++ b/src/status.h @@ -258,6 +258,13 @@ typedef enum { JSStreamMoveInProgressErr = 10124, ///< Stream move already in progress JSConsumerMaxRequestBatchExceededErr = 10125, ///< Consumer max request batch exceeds server limit JSConsumerReplicasExceedsStreamErr = 10126, ///< Consumer config replica count exceeds parent stream + JSConsumerNameContainsPathSeparatorsErr = 10127, ///< Consumer name can not contain path separators + JSStreamNameContainsPathSeparatorsErr = 10128, ///< Stream name can not contain path separators + JSStreamMoveNotInProgressErr = 10129, ///< Stream move not in progress + JSStreamNameExistRestoreFailedErr = 10130, ///< Stream name already in use, cannot restore + JSConsumerCreateFilterSubjectMismatchErr = 10131, ///< Consumer create request did not match filtered subject from create subject + JSConsumerCreateDurableAndNameMismatchErr = 10132, ///< Consumer Durable and Name have to be equal if both are provided + JSReplicasCountCannotBeNegativeErr = 10133, ///< Replicas count cannot be negative } jsErrCode; diff --git a/src/version.h b/src/version.h index c766eaaef..a0e6ebdef 100644 --- a/src/version.h +++ b/src/version.h @@ -22,16 +22,16 @@ extern "C" { #endif #define NATS_VERSION_MAJOR 3 -#define NATS_VERSION_MINOR 4 -#define NATS_VERSION_PATCH 1 +#define NATS_VERSION_MINOR 5 +#define NATS_VERSION_PATCH 0 -#define NATS_VERSION_STRING "3.4.1" +#define NATS_VERSION_STRING "3.5.0-dev" #define NATS_VERSION_NUMBER ((NATS_VERSION_MAJOR << 16) | \ (NATS_VERSION_MINOR << 8) | \ NATS_VERSION_PATCH) -#define NATS_VERSION_REQUIRED_NUMBER 0x030400 +#define NATS_VERSION_REQUIRED_NUMBER 0x030500 #ifdef __cplusplus } diff --git a/test/list.txt b/test/list.txt index 38f5138ef..ebc513c84 100644 --- a/test/list.txt +++ b/test/list.txt @@ -241,6 +241,7 @@ JetStreamDirectGetMsg JetStreamNakWithDelay JetStreamBackOffRedeliveries JetStreamInfoWithSubjects +JetStreamInfoAlternates KeyValueManager KeyValueBasics KeyValueWatch @@ -253,6 +254,7 @@ KeyValueCrossAccount KeyValueDiscardOldToNew KeyValueRePublish KeyValueMirrorDirectGet +KeyValueMirrorCrossDomains StanPBufAllocator StanConnOptions StanSubOptions diff --git a/test/test.c b/test/test.c index 7dd78270c..3d5dc66ce 100644 --- a/test/test.c +++ b/test/test.c @@ -5509,7 +5509,8 @@ _stopServer(natsPid pid) CloseHandle(pid->hThread); natsMutex_Lock(slMu); - natsHash_Remove(slMap, (int64_t) pid); + if (slMap != NULL) + natsHash_Remove(slMap, (int64_t) pid); natsMutex_Unlock(slMu); free(pid); @@ -5614,7 +5615,8 @@ _startServerImpl(const char *serverExe, const char *url, const char *cmdLineOpts } natsMutex_Lock(slMu); - natsHash_Set(slMap, (int64_t) pid, NULL, NULL); + if (slMap != NULL) + natsHash_Set(slMap, (int64_t) pid, NULL, NULL); natsMutex_Unlock(slMu); return (natsPid) pid; @@ -5644,7 +5646,8 @@ _stopServer(natsPid pid) waitpid(pid, &status, 0); natsMutex_Lock(slMu); - natsHash_Remove(slMap, (int64_t) pid); + if (slMap != NULL) + natsHash_Remove(slMap, (int64_t) pid); natsMutex_Unlock(slMu); } @@ -5720,7 +5723,8 @@ _startServerImpl(const char *serverExe, const char *url, const char *cmdLineOpts } natsMutex_Lock(slMu); - natsHash_Set(slMap, (int64_t) pid, NULL, NULL); + if (slMap != NULL) + natsHash_Set(slMap, (int64_t) pid, NULL, NULL); natsMutex_Unlock(slMu); // parent, return the child's PID back. @@ -21728,8 +21732,11 @@ test_JetStreamUnmarshalStreamInfo(void) "{\"cluster\":{\"name\":\"S1\",\"leader\":\"S2\",\"replicas\":[{\"name\":\"S1\",\"current\":true,\"offline\":false,\"active\":123,\"lag\":456},{\"name\":\"S1\",\"current\":false,\"offline\":true,\"active\":123,\"lag\":456}]}}", "{\"mirror\":{\"name\":\"M\",\"lag\":123,\"active\":456}}", "{\"mirror\":{\"name\":\"M\",\"external\":{\"api\":\"MyApi\",\"deliver\":\"deliver.prefix\"},\"lag\":123,\"active\":456}}", + "{\"sources\":[{\"name\":\"S1\",\"lag\":123,\"active\":456}]}", "{\"sources\":[{\"name\":\"S1\",\"lag\":123,\"active\":456},{\"name\":\"S2\",\"lag\":123,\"active\":456}]}", "{\"sources\":[{\"name\":\"S1\",\"external\":{\"api\":\"MyApi\",\"deliver\":\"deliver.prefix\"},\"lag\":123,\"active\":456},{\"name\":\"S2\",\"lag\":123,\"active\":456}]}", + "{\"alternates\":[{\"name\":\"S1\",\"domain\":\"domain\",\"cluster\":\"abc\"}]}", + "{\"alternates\":[{\"name\":\"S1\",\"domain\":\"domain\",\"cluster\":\"abc\"},{\"name\":\"S2\",\"domain\":\"domain\",\"cluster\":\"abc\"}]}", }; const char *bad[] = { "{\"config\":123}", @@ -21777,6 +21784,10 @@ test_JetStreamUnmarshalStreamInfo(void) "{\"sources\":[{\"name\":123}]}", "{\"sources\":[{\"name\":\"S1\",\"external\":123}]}", "{\"sources\":[{\"name\":\"S1\",\"external\":{\"deliver\":123}}]}", + "{\"alternates\":123}", + "{\"alternates\":[{\"name\":123}]}", + "{\"alternates\":[{\"name\":\"S1\",\"domain\":123}]}", + "{\"alternates\":[{\"name\":\"S1\",\"domain\":\"domain\",\"cluster\":123}]}", }; int i; char tmp[64]; @@ -22683,6 +22694,8 @@ test_JetStreamMgtStreams(void) jsStreamInfoList *siList = NULL; jsStreamNamesList *snList = NULL; int count = 0; + jsStreamSource ss; + jsExternalStream se; jsOptions o; int i; @@ -23107,6 +23120,7 @@ test_JetStreamMgtStreams(void) natsMsg_GetData(resp), natsMsg_GetDataLength(resp)) == 0)); jsStreamInfo_Destroy(si); + si = NULL; natsMsg_Destroy(resp); resp = NULL; @@ -23150,6 +23164,7 @@ test_JetStreamMgtStreams(void) && (strcmp(si->Config->Subjects[0], "foo.>") == 0) && (strcmp(si->Config->Subjects[1], "bar.*") == 0)); jsStreamInfo_Destroy(si); + si = NULL; test("List stream infos (bad args): "); s = js_Streams(NULL, js, NULL, NULL); @@ -23286,6 +23301,35 @@ test_JetStreamMgtStreams(void) s = js_StreamNames(&snList, js, &o, &jerr); testCond((s == NATS_NOT_FOUND) && (snList == NULL)); + test("Mirror domain and external set error: "); + jsStreamConfig_Init(&cfg); + cfg.Name = "MDESET"; + jsStreamSource_Init(&ss); + ss.Domain = "Domain"; + jsExternalStream_Init(&se); + se.DeliverPrefix = "some.prefix"; + ss.External = &se; + cfg.Mirror = &ss; + s = js_AddStream(&si, js, &cfg, NULL, NULL); + testCond((s == NATS_INVALID_ARG) && (si == NULL) + && (strstr(nats_GetLastError(NULL), "domain and external are both set") != NULL)); + nats_clearLastError(); + + test("Source domain and external set error: "); + jsStreamConfig_Init(&cfg); + cfg.Name = "SDESET"; + jsStreamSource_Init(&ss); + ss.Domain = "Domain"; + jsExternalStream_Init(&se); + se.DeliverPrefix = "some.prefix"; + ss.External = &se; + cfg.Sources = (jsStreamSource*[1]){&ss}; + cfg.SourcesLen = 1; + s = js_AddStream(&si, js, &cfg, NULL, NULL); + testCond((s == NATS_INVALID_ARG) && (si == NULL) + && (strstr(nats_GetLastError(NULL), "domain and external are both set") != NULL)); + nats_clearLastError(); + JS_TEARDOWN; } @@ -29701,6 +29745,137 @@ test_JetStreamInfoWithSubjects(void) JS_TEARDOWN; } +static natsStatus +_checkJSClusterReady(const char *url) +{ + natsStatus s = NATS_OK; + natsConnection *nc = NULL; + jsCtx *js = NULL; + jsErrCode jerr= 0; + int i; + jsOptions jo; + + jsOptions_Init(&jo); + jo.Wait = 1000; + + s = natsConnection_ConnectTo(&nc, url); + IFOK(s, natsConnection_JetStream(&js, nc, &jo)); + for (i=0; (s == NATS_OK) && (i<10); i++) + { + jsStreamInfo *si = NULL; + + s = js_GetStreamInfo(&si, js, "CHECK_CLUSTER", &jo, &jerr); + if (jerr == JSStreamNotFoundErr) + { + nats_clearLastError(); + s = NATS_OK; + break; + } + if ((s != NATS_OK) && (i < 9)) + { + s = NATS_OK; + nats_Sleep(500); + } + } + jsCtx_Destroy(js); + natsConnection_Destroy(nc); + return s; +} + +static void +test_JetStreamInfoAlternates(void) +{ + char datastore1[256] = {'\0'}; + char datastore2[256] = {'\0'}; + char datastore3[256] = {'\0'}; + char cmdLine[1024] = {'\0'}; + natsPid pid1 = NATS_INVALID_PID; + natsPid pid2 = NATS_INVALID_PID; + natsPid pid3 = NATS_INVALID_PID; + natsConnection *nc = NULL; + jsCtx *js = NULL; + jsStreamInfo *si = NULL; + jsStreamConfig sc; + jsStreamSource ss; + natsStatus s; + + ENSURE_JS_VERSION(2, 9, 0); + + test("Start cluster: "); + _makeUniqueDir(datastore1, sizeof(datastore1), "datastore_"); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -cluster_name abc -server_name A -cluster nats://127.0.0.1:6222 -routes nats://127.0.0.1:6222,nats://127.0.0.1:6223,nats://127.0.0.1:6224 -p 4222", datastore1); + pid1 = _startServer("nats://127.0.0.1:4222", cmdLine, true); + CHECK_SERVER_STARTED(pid1); + + _makeUniqueDir(datastore2, sizeof(datastore2), "datastore_"); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -cluster_name abc -server_name B -cluster nats://127.0.0.1:6223 -routes nats://127.0.0.1:6222,nats://127.0.0.1:6223,nats://127.0.0.1:6224 -p 4223", datastore2); + pid2 = _startServer("nats://127.0.0.1:4223", cmdLine, true); + CHECK_SERVER_STARTED(pid1); + + _makeUniqueDir(datastore3, sizeof(datastore3), "datastore_"); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -cluster_name abc -server_name C -cluster nats://127.0.0.1:6224 -routes nats://127.0.0.1:6222,nats://127.0.0.1:6223,nats://127.0.0.1:6224 -p 4224", datastore3); + pid3 = _startServer("nats://127.0.0.1:4224", cmdLine, true); + CHECK_SERVER_STARTED(pid1); + testCond(true); + + test("Check cluster: "); + s = _checkJSClusterReady("nats://127.0.0.1:4224"); + testCond(s == NATS_OK); + + test("Connect: "); + s = natsConnection_ConnectTo(&nc, NATS_DEFAULT_URL); + testCond(s == NATS_OK); + + test("Get context: "); + s = natsConnection_JetStream(&js, nc, NULL); + testCond(s == NATS_OK); + + test("Create stream: "); + jsStreamConfig_Init(&sc); + sc.Name = "TEST"; + sc.Subjects = (const char*[1]){"foo"}; + sc.SubjectsLen = 1; + s = js_AddStream(NULL, js, &sc, NULL, NULL); + testCond(s == NATS_OK); + + test("Create mirror: "); + jsStreamConfig_Init(&sc); + sc.Name = "MIRROR"; + jsStreamSource_Init(&ss); + ss.Name = "TEST"; + sc.Mirror = &ss; + s = js_AddStream(NULL, js, &sc, NULL, NULL); + testCond(s == NATS_OK); + + test("Check for alternate: "); + s = js_GetStreamInfo(&si, js, "TEST", NULL, NULL); + testCond((s == NATS_OK) && (si != NULL) && (si->AlternatesLen == 2)); + + test("Check alternate content: "); + if ((strcmp(si->Alternates[0]->Cluster, "abc") != 0) + || (strcmp(si->Alternates[1]->Cluster, "abc") != 0)) + { + s = NATS_ERR; + } + else if (((strcmp(si->Alternates[0]->Name, "TEST") == 0) && (strcmp(si->Alternates[1]->Name, "MIRROR") != 0)) + || ((strcmp(si->Alternates[0]->Name, "MIRROR") == 0) && (strcmp(si->Alternates[1]->Name, "TEST") != 0))) + { + s = NATS_ERR; + } + testCond(s == NATS_OK); + jsStreamInfo_Destroy(si); + + jsCtx_Destroy(js); + natsConnection_Destroy(nc); + + _stopServer(pid3); + _stopServer(pid2); + _stopServer(pid1); + rmtree(datastore1); + rmtree(datastore2); + rmtree(datastore3); +} + static void test_KeyValueManager(void) { @@ -29882,6 +30057,13 @@ test_KeyValueBasics(void) s = (kvStore_Bucket(NULL) == NULL ? NATS_OK : NATS_ERR); testCond(s == NATS_OK); + test("Check bytes is 0: "); + s = kvStore_Status(&sts, kv); + IFOK(s, (kvStatus_Bytes(sts) == 0 ? NATS_OK : NATS_ERR)); + testCond(s == NATS_OK); + kvStatus_Destroy(sts); + sts = NULL; + test("Simple put (bad args): "); rev = 1234; s = kvStore_Put(&rev, NULL, "key", (const void*) "value", 5); @@ -30107,9 +30289,24 @@ test_KeyValueBasics(void) s = (kvStatus_Replicas(sts) == 1 ? NATS_OK : NATS_ERR); testCond(s == NATS_OK); + test("Check bytes: "); + { + jsStreamInfo *si = NULL; + + if (i == 0) + s = js_GetStreamInfo(&si, js, "KV_TEST0", NULL, NULL); + else + s = js_GetStreamInfo(&si, js, "KV_TEST1", NULL, NULL); + IFOK(s, (kvStatus_Bytes(sts) == si->State.Bytes ? NATS_OK : NATS_ERR)); + + jsStreamInfo_Destroy(si); + } + testCond(s == NATS_OK); + test("Check status with NULL: "); if ((kvStatus_History(NULL) != 0) || (kvStatus_Bucket(NULL) != NULL) - || (kvStatus_TTL(NULL) != 0) || (kvStatus_Values(NULL) != 0)) + || (kvStatus_TTL(NULL) != 0) || (kvStatus_Values(NULL) != 0) + || (kvStatus_Bytes(NULL) != 0)) { s = NATS_ERR; } @@ -31030,50 +31227,48 @@ static void test_KeyValueDiscardOldToNew(void) { kvStore *kv = NULL; - kvEntry *e = NULL; kvConfig kvc; natsStatus s; - int i; JS_SETUP(2, 7, 2); - // We are going to go from 2.7.1->2.7.2->2.7.1 and 2.7.2 again. - for (i=0; i<2; i++) - { - // Change the server version in the connection to - // create as-if we were connecting to a v2.7.1 server. - natsConn_Lock(nc); - nc->srvVersion.ma = 2; - nc->srvVersion.mi = 7; - nc->srvVersion.up = 1; - natsConn_Unlock(nc); + // Change the server version in the connection to + // create as-if we were connecting to a v2.7.1 server. + natsConn_Lock(nc); + nc->srvVersion.ma = 2; + nc->srvVersion.mi = 7; + nc->srvVersion.up = 1; + natsConn_Unlock(nc); - test("Check discard (old): "); - s = _checkDiscard(js, js_DiscardOld, &kv); - if ((s == NATS_OK) && (i == 0)) - s = kvStore_PutString(NULL, kv, "foo", "value"); - testCond(s == NATS_OK); - kvStore_Destroy(kv); - kv = NULL; + test("Check discard (old): "); + s = _checkDiscard(js, js_DiscardOld, &kv); + testCond(s == NATS_OK); + kvStore_Destroy(kv); + kv = NULL; - // Now change version to 2.7.2 - natsConn_Lock(nc); - nc->srvVersion.ma = 2; - nc->srvVersion.mi = 7; - nc->srvVersion.up = 2; - natsConn_Unlock(nc); + // Now change version to 2.7.2 + natsConn_Lock(nc); + nc->srvVersion.ma = 2; + nc->srvVersion.mi = 7; + nc->srvVersion.up = 2; + natsConn_Unlock(nc); - test("Check discard (new): "); - s = _checkDiscard(js, js_DiscardNew, &kv); - IFOK(s, kvStore_Get(&e, kv, "foo")); - if ((s == NATS_OK) && (strcmp(kvEntry_ValueString(e), "value") != 0)) - s = NATS_ERR; - testCond(s == NATS_OK); - kvEntry_Destroy(e); - e = NULL; - kvStore_Destroy(kv); - kv = NULL; - } + test("Check discard (old, no auto-update): "); + s = _checkDiscard(js, js_DiscardOld, &kv); + testCond((s == NATS_ERR) && (kv == NULL) + && (strstr(nats_GetLastError(NULL), "different configuration") != NULL)); + nats_clearLastError(); + + // Now delete the kv store and create against 2.7.2+ + test("Delete KV: "); + s = js_DeleteStream(js, "KV_TEST", NULL, NULL); + testCond(s == NATS_OK); + + test("Check discard (new): "); + s = _checkDiscard(js, js_DiscardNew, &kv); + testCond(s == NATS_OK); + kvStore_Destroy(kv); + kv = NULL; test("Check that other changes are rejected: "); kvConfig_Init(&kvc); @@ -31081,7 +31276,7 @@ test_KeyValueDiscardOldToNew(void) kvc.MaxBytes = 1024*1024; s = js_CreateKeyValue(&kv, js, &kvc); testCond((s == NATS_ERR) - && (strstr(nats_GetLastError(NULL), "configuration is different") != NULL)); + && (strstr(nats_GetLastError(NULL), "different configuration") != NULL)); kvStore_Destroy(kv); JS_TEARDOWN; @@ -31115,7 +31310,7 @@ test_KeyValueRePublish(void) rp.Destination = "bar.>"; kvc.RePublish =&rp; s = js_CreateKeyValue(&kv, js, &kvc); - testCond((s == NATS_ERR) && (strstr(nats_GetLastError(NULL), "can not change RePublish") != NULL)); + testCond((s == NATS_ERR) && (strstr(nats_GetLastError(NULL), "different configuration") != NULL)); nats_clearLastError(); test("Create with repub: "); @@ -31215,6 +31410,356 @@ test_KeyValueMirrorDirectGet(void) JS_TEARDOWN; } +static natsStatus +_connectToHubAndCheckLeaf(natsConnection **hub, natsConnection *lnc) +{ + natsStatus s = NATS_OK; + natsConnection *nc = NULL; + natsSubscription *sub = NULL; + int i; + + s = natsConnection_ConnectTo(&nc, NATS_DEFAULT_URL); + IFOK(s, natsConnection_SubscribeSync(&sub, nc, "check")); + IFOK(s, natsConnection_Flush(nc)); + if (s == NATS_OK) + { + for (i=0; i<10; i++) + { + s = natsConnection_PublishString(lnc, "check", "hello"); + if (s == NATS_OK) + { + natsMsg *msg = NULL; + s = natsSubscription_NextMsg(&msg, sub, 500); + natsMsg_Destroy(msg); + if (s == NATS_OK) + break; + } + } + } + natsSubscription_Destroy(sub); + if (s == NATS_OK) + *hub = nc; + else + natsConnection_Destroy(nc); + return s; +} + +static void +test_KeyValueMirrorCrossDomains(void) +{ + natsStatus s; + natsConnection *nc = NULL; + natsConnection *lnc= NULL; + jsCtx *js = NULL; + jsCtx *ljs= NULL; + jsCtx *rjs= NULL; + natsPid pid = NATS_INVALID_PID; + natsPid pid2= NATS_INVALID_PID; + jsOptions o; + jsErrCode jerr = 0; + char datastore[256] = {'\0'}; + char datastore2[256] = {'\0'}; + char cmdLine[1024] = {'\0'}; + char confFile[256] = {'\0'}; + char lconfFile[256] = {'\0'}; + kvStore *kv = NULL; + kvStore *lkv = NULL; + kvStore *mkv = NULL; + kvStore *rkv = NULL; + kvEntry *e = NULL; + jsStreamInfo *si = NULL; + kvWatcher *w = NULL; + int ok = 0; + kvPurgeOptions po; + kvConfig kvc; + jsStreamSource src; + int i; + + ENSURE_JS_VERSION(2, 9, 0); + + _makeUniqueDir(datastore, sizeof(datastore), "datastore_"); + _createConfFile(confFile, sizeof(confFile), + "server_name: HUB\n"\ + "listen: 127.0.0.1:4222\n"\ + "jetstream: { domain: HUB }\n"\ + "leafnodes { listen: 127.0.0.1:7422 }\n"); + + test("Start hub: "); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -c %s", datastore, confFile); + pid = _startServer("nats://127.0.0.1:4222", cmdLine, true); + CHECK_SERVER_STARTED(pid); + testCond(true); + + _makeUniqueDir(datastore2, sizeof(datastore2), "datastore_"); + _createConfFile(lconfFile, sizeof(lconfFile), + "server_name: LEAF\n"\ + "listen: 127.0.0.1:4223\n"\ + "jetstream: { domain: LEAF }\n"\ + "leafnodes {\n"\ + " remotes = [ { url: leaf://127.0.0.1:7422 } ]\n"\ + "}\n"); + + test("Start leaf: "); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -c %s", datastore, lconfFile); + pid2 = _startServer("nats://127.0.0.1:4223", cmdLine, true); + CHECK_SERVER_STARTED(pid2); + testCond(true); + + test("Connect to leaf: "); + s = natsConnection_ConnectTo(&lnc, "nats://127.0.0.1:4223"); + testCond(s == NATS_OK); + + test("Get context: "); + s = natsConnection_JetStream(&ljs, lnc, NULL); + testCond(s == NATS_OK); + + test("Connect to hub and check connectivity through leaf: "); + s = _connectToHubAndCheckLeaf(&nc, lnc); + testCond(s == NATS_OK); + + test("Get context: "); + s = natsConnection_JetStream(&js, nc, NULL); + testCond(s == NATS_OK); + + test("Create KV value: "); + kvConfig_Init(&kvc); + kvc.Bucket = "TEST"; + s = js_CreateKeyValue(&kv, js, &kvc); + testCond(s == NATS_OK); + + test("Put keys: "); + s = kvStore_PutString(NULL, kv, "name", "derek"); + IFOK(s, kvStore_PutString(NULL, kv, "age", "22")); + testCond(s == NATS_OK); + + test("Create KV: "); + kvConfig_Init(&kvc); + kvc.Bucket = "MIRROR"; + jsStreamSource_Init(&src); + src.Name = "TEST"; + src.Domain = "HUB"; + kvc.Mirror = &src; + s = js_CreateKeyValue(&lkv, ljs, &kvc); + testCond(s == NATS_OK); + + test("Check config not changed: "); + testCond((strcmp(kvc.Bucket, "MIRROR") == 0) + && (kvc.Mirror != NULL) + && (strcmp(kvc.Mirror->Name, "TEST") == 0) + && (strcmp(kvc.Mirror->Domain, "HUB") == 0) + && (kvc.Mirror->External == NULL)); + + test("Get stream info: "); + s = js_GetStreamInfo(&si, ljs, "KV_MIRROR", NULL, &jerr); + testCond((s == NATS_OK) && (si != NULL) && (jerr == 0)); + + test("Check mirror direct: "); + testCond(si->Config->MirrorDirect); + jsStreamInfo_Destroy(si); + si = NULL; + + test("Check mirror syncs: "); + for (i=0; i<10; i++) + { + s = js_GetStreamInfo(&si, ljs, "KV_MIRROR", NULL, NULL); + if (s != NATS_OK) + break; + + if (si->State.Msgs != 2) + s = NATS_ERR; + + jsStreamInfo_Destroy(si); + si = NULL; + if (s == NATS_OK) + break; + nats_Sleep(250); + } + testCond(s == NATS_OK); + + // Bind locally from leafnode and make sure both get and put work. + test("Leaf KV: "); + s = js_KeyValue(&mkv, ljs, "MIRROR"); + testCond(s == NATS_OK); + + test("Put key: "); + s = kvStore_PutString(NULL, mkv, "name", "rip"); + testCond(s == NATS_OK); + + test("Get key: "); + s = kvStore_Get(&e, mkv, "name"); + if ((s == NATS_OK) && (e != NULL)) + s = (strcmp(kvEntry_ValueString(e), "rip") == 0 ? NATS_OK : NATS_ERR); + testCond(s == NATS_OK); + kvEntry_Destroy(e); + e = NULL; + + test("Get context for HUB: "); + jsOptions_Init(&o); + o.Domain = "HUB"; + s = natsConnection_JetStream(&rjs, lnc, &o); + testCond(s == NATS_OK); + + test("Get KV: "); + s = js_KeyValue(&rkv, rjs, "TEST"); + testCond(s == NATS_OK); + + test("Put key: "); + s = kvStore_PutString(NULL, rkv, "name", "ivan"); + testCond(s == NATS_OK); + + test("Get key: "); + s = kvStore_Get(&e, rkv, "name"); + if ((s == NATS_OK) && (e != NULL)) + s = (strcmp(kvEntry_ValueString(e), "ivan") == 0 ? NATS_OK : NATS_ERR); + testCond(s == NATS_OK); + kvEntry_Destroy(e); + e = NULL; + + test("Shutdown hub: "); + jsCtx_Destroy(js); + kvStore_Destroy(kv); + natsConnection_Destroy(nc); + nc = NULL; + _stopServer(pid); + pid = NATS_INVALID_PID; + testCond(true); + nats_Sleep(500); + + test("Get key: "); + // Use mkv here, not rkv. + s = kvStore_Get(&e, mkv, "name"); + if ((s == NATS_OK) && (e != NULL)) + s = (strcmp(kvEntry_ValueString(e), "ivan") == 0 ? NATS_OK : NATS_ERR); + testCond(s == NATS_OK); + kvEntry_Destroy(e); + e = NULL; + + test("Create watcher (name): "); + s = kvStore_Watch(&w, mkv, "name", NULL); + testCond(s == NATS_OK); + + test("Check watcher: "); + s = kvWatcher_Next(&e, w, 1000); + if (s == NATS_OK) + { + if ((strcmp(kvEntry_Key(e), "name") != 0) || (strcmp(kvEntry_ValueString(e), "ivan") != 0)) + s = NATS_ERR; + kvEntry_Destroy(e); + e = NULL; + } + IFOK(s, kvWatcher_Next(&e, w, 1000)); + if (s == NATS_OK) + { + if ((kvEntry_Key(e) != NULL) || (kvEntry_ValueString(e) != NULL)) + s = NATS_ERR; + kvEntry_Destroy(e); + e = NULL; + } + testCond(s == NATS_OK); + + test("No more: "); + s = kvWatcher_Next(&e, w, 250); + testCond((s == NATS_TIMEOUT) && (e == NULL)); + nats_clearLastError(); + + kvWatcher_Destroy(w); + w = NULL; + + test("Create watcher (all): ") + s = kvStore_WatchAll(&w, mkv, NULL); + testCond((s == NATS_OK) && (w != NULL)); + + test("Check watcher: "); + s = kvWatcher_Next(&e, w, 1000); + if (s == NATS_OK) + { + if ((strcmp(kvEntry_Key(e), "age") != 0) || (strcmp(kvEntry_ValueString(e), "22") != 0)) + s = NATS_ERR; + kvEntry_Destroy(e); + e = NULL; + } + IFOK(s, kvWatcher_Next(&e, w, 1000)); + if (s == NATS_OK) + { + if ((strcmp(kvEntry_Key(e), "name") != 0) || (strcmp(kvEntry_ValueString(e), "ivan") != 0)) + s = NATS_ERR; + kvEntry_Destroy(e); + e = NULL; + } + IFOK(s, kvWatcher_Next(&e, w, 1000)); + if (s == NATS_OK) + { + if ((kvEntry_Key(e) != NULL) || (kvEntry_ValueString(e) != NULL)) + s = NATS_ERR; + kvEntry_Destroy(e); + e = NULL; + } + testCond(s == NATS_OK); + + test("No more: "); + s = kvWatcher_Next(&e, w, 250); + testCond((s == NATS_TIMEOUT) && (e == NULL)); + nats_clearLastError(); + + test("Restart hub: "); + snprintf(cmdLine, sizeof(cmdLine), "-js -sd %s -c %s", datastore, confFile); + pid = _startServer("nats://127.0.0.1:4222", cmdLine, true); + CHECK_SERVER_STARTED(pid); + testCond(true); + + test("Connect to hub and check connectivity through leaf: "); + s = _connectToHubAndCheckLeaf(&nc, lnc); + testCond(s == NATS_OK); + + test("Delete keys: "); + s = kvStore_Delete(mkv, "age"); + IFOK(s, kvStore_Delete(mkv, "name")); + testCond(s == NATS_OK); + + test("Check mirror syncs: "); + for (i=0; (ok != 2) && (i < 10); i++) + { + if (kvWatcher_Next(&e, w, 1000) == NATS_OK) + { + if (((strcmp(kvEntry_Key(e), "age") == 0) || (strcmp(kvEntry_Key(e), "name") == 0)) + && (kvEntry_Operation(e) == kvOp_Delete)) + { + ok++; + } + kvEntry_Destroy(e); + e = NULL; + } + } + testCond((s == NATS_OK) && (ok == 2)); + + test("Purge deletes: "); + kvPurgeOptions_Init(&po); + po.DeleteMarkersOlderThan = -1; + s = kvStore_PurgeDeletes(mkv, &po); + testCond(s == NATS_OK); + + nats_clearLastError(); + test("Check stream: "); + s = js_GetStreamInfo(&si, ljs, "KV_MIRROR", NULL, NULL); + testCond((s == NATS_OK) && (si != NULL) && (si->State.Msgs == 0)); + jsStreamInfo_Destroy(si); + + kvWatcher_Destroy(w); + natsConnection_Destroy(nc); + kvStore_Destroy(rkv); + kvStore_Destroy(mkv); + kvStore_Destroy(lkv); + jsCtx_Destroy(rjs); + jsCtx_Destroy(ljs); + natsConnection_Destroy(lnc); + _stopServer(pid2); + rmtree(datastore2); + _stopServer(pid); + rmtree(datastore); + remove(confFile); + remove(lconfFile); +} + #if defined(NATS_HAS_STREAMING) static int @@ -33670,6 +34215,7 @@ static testInfo allTests[] = {"JetStreamNakWithDelay", test_JetStreamNakWithDelay}, {"JetStreamBackOffRedeliveries", test_JetStreamBackOffRedeliveries}, {"JetStreamInfoWithSubjects", test_JetStreamInfoWithSubjects}, + {"JetStreamInfoAlternates", test_JetStreamInfoAlternates}, {"KeyValueManager", test_KeyValueManager}, {"KeyValueBasics", test_KeyValueBasics}, @@ -33683,6 +34229,7 @@ static testInfo allTests[] = {"KeyValueDiscardOldToNew", test_KeyValueDiscardOldToNew}, {"KeyValueRePublish", test_KeyValueRePublish}, {"KeyValueMirrorDirectGet", test_KeyValueMirrorDirectGet}, + {"KeyValueMirrorCrossDomains", test_KeyValueMirrorCrossDomains}, #if defined(NATS_HAS_STREAMING) {"StanPBufAllocator", test_StanPBufAllocator}, @@ -33848,16 +34395,34 @@ int main(int argc, char **argv) // Shutdown servers that are still running likely due to failed test { + natsHash *pids = NULL; natsHashIter iter; int64_t key; - natsMutex_Lock(slMu); - natsHashIter_Init(&iter, slMap); + if (natsHash_Create(&pids, 16) == NATS_OK) + { + natsMutex_Lock(slMu); + natsHashIter_Init(&iter, slMap); + while (natsHashIter_Next(&iter, &key, NULL)) + { + natsHash_Set(pids, key, NULL, NULL); + natsHashIter_RemoveCurrent(&iter); + } + natsHashIter_Done(&iter); + natsHash_Destroy(slMap); + slMap = NULL; + natsMutex_Unlock(slMu); - while (natsHashIter_Next(&iter, &key, NULL)) - _stopServer((natsPid) key); + natsHashIter_Init(&iter, pids); + while (natsHashIter_Next(&iter, &key, NULL)) + _stopServer((natsPid) key); - natsHash_Destroy(slMap); + natsHash_Destroy(pids); + } + else + { + natsHash_Destroy(slMap); + } natsMutex_Destroy(slMu); }