From e18710da81b4c53b357dde2ca55005344edc314f Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Wed, 9 Oct 2019 19:44:03 +0200 Subject: [PATCH] add first documentation draft and framework --- doc/Doxyfile.in | 35 +++ doc/_static/custom.css | 0 doc/_static/libecoli.svg | 92 +++++++ doc/architecture.rst | 153 ++++++++++++ doc/conf.py | 178 ++++++++++++++ doc/contributing.rst | 7 + doc/index.rst | 45 ++++ doc/installation.rst | 7 + doc/meson.build | 39 +++ doc/overview.rst | 7 + doc/parse-tree.svg | 212 +++++++++++++++++ doc/parse-tree2.svg | 449 +++++++++++++++++++++++++++++++++++ doc/parse-tree3.svg | 360 ++++++++++++++++++++++++++++ doc/simple-tree.svg | 204 ++++++++++++++++ doc/simple-tree2.svg | 204 ++++++++++++++++ doc/simple-tree3.svg | 121 ++++++++++ doc/user_guide.rst | 7 + include/ecoli.h | 66 +++++ include/ecoli_assert.h | 7 +- include/ecoli_complete.h | 7 +- include/ecoli_config.h | 9 + include/ecoli_dict.h | 7 +- include/ecoli_editline.h | 5 + include/ecoli_htable.h | 7 +- include/ecoli_init.h | 7 +- include/ecoli_log.h | 7 +- include/ecoli_malloc.h | 7 + include/ecoli_murmurhash.h | 7 + include/ecoli_node.h | 14 +- include/ecoli_node_any.h | 5 + include/ecoli_node_bypass.h | 5 + include/ecoli_node_cmd.h | 7 + include/ecoli_node_cond.h | 5 + include/ecoli_node_dynamic.h | 7 + include/ecoli_node_empty.h | 5 + include/ecoli_node_expr.h | 7 + include/ecoli_node_file.h | 7 + include/ecoli_node_int.h | 8 +- include/ecoli_node_many.h | 7 + include/ecoli_node_none.h | 9 +- include/ecoli_node_once.h | 7 + include/ecoli_node_option.h | 7 + include/ecoli_node_or.h | 8 +- include/ecoli_node_re.h | 7 + include/ecoli_node_re_lex.h | 7 + include/ecoli_node_seq.h | 7 + include/ecoli_node_sh_lex.h | 7 + include/ecoli_node_space.h | 5 + include/ecoli_node_str.h | 7 + include/ecoli_node_subset.h | 7 + include/ecoli_parse.h | 7 + include/ecoli_string.h | 7 + include/ecoli_strvec.h | 7 +- include/ecoli_test.h | 9 + include/ecoli_utils.h | 10 + include/ecoli_vec.h | 7 +- include/ecoli_yaml.h | 7 + include/meson.build | 1 + meson.build | 1 + 59 files changed, 2452 insertions(+), 15 deletions(-) create mode 100644 doc/Doxyfile.in create mode 100644 doc/_static/custom.css create mode 100644 doc/_static/libecoli.svg create mode 100644 doc/architecture.rst create mode 100644 doc/conf.py create mode 100644 doc/contributing.rst create mode 100644 doc/index.rst create mode 100644 doc/installation.rst create mode 100644 doc/meson.build create mode 100644 doc/overview.rst create mode 100644 doc/parse-tree.svg create mode 100644 doc/parse-tree2.svg create mode 100644 doc/parse-tree3.svg create mode 100644 doc/simple-tree.svg create mode 100644 doc/simple-tree2.svg create mode 100644 doc/simple-tree3.svg create mode 100644 doc/user_guide.rst create mode 100644 include/ecoli.h diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 0000000..274c476 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,35 @@ +PROJECT_NAME = "Libecoli" +PROJECT_BRIEF = "Extensible Command Line library" +PROJECT_NUMBER = @VERSION@ +INPUT = @TOPDIR@/include +OUTPUT_DIRECTORY = @OUTPUT@ +FILE_PATTERNS = *.c *.h *.dox + +BRIEF_MEMBER_DESC = YES +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +INLINE_SIMPLE_STRUCTS = YES +EXTRACT_ALL = YES +SOURCE_BROWSER = YES +REPEAT_BRIEF = NO + +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO + +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +SOURCE_BROWSER = YES + +GENERATE_XML = YES +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES + +GENERATE_LATEX = NO +HAVE_DOT = NO \ No newline at end of file diff --git a/doc/_static/custom.css b/doc/_static/custom.css new file mode 100644 index 0000000..e69de29 diff --git a/doc/_static/libecoli.svg b/doc/_static/libecoli.svg new file mode 100644 index 0000000..605b9fd --- /dev/null +++ b/doc/_static/libecoli.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + libecoli> + + + diff --git a/doc/architecture.rst b/doc/architecture.rst new file mode 100644 index 0000000..64ecaa8 --- /dev/null +++ b/doc/architecture.rst @@ -0,0 +1,153 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +Architecture +============ + +Most of *libecoli* is written in C. It provides a C API to ease the +creation of interactive command line interfaces. It is split in several +parts: + +- the core: it provides the main API to parse and complete strings. +- ecoli nodes: this is the modular part of *libecoli*. Each node + implements a specific parsing (integers, strings, regular expressions, + sequence, ...) +- yaml parser: load an ecoli tree described in yaml. +- editline: helpers to instantiate an *editline* and connect it to + *libecoli*. +- utilities: logging, string, strings vector, hash table, ... + +The grammar tree +---------------- + +The *ecoli nodes* are organized in a tree. An *ecoli grammar tree* +describes how the input is parsed and completed. Let's take a simple +example: + +.. figure:: simple-tree.svg + + A simple *ecoli grammar tree*. + +We can also represent it as text like this:: + + sh_lex( + seq( + str(foo), + option( + str(bar) + ) + ) + ) + +This tree matches the following strings: + +- ``foo`` +- ``foo bar`` + +But, for instance, it does **not** match the following strings: + +- ``bar`` +- ``foobar`` +- (empty string) + +Parsing an input +---------------- + +When the *libecoli* parses an input, it browses the tree (depth first +search) and returns an *ecoli parse tree*. Let's decompose what is done +when ``ec_node_parse_strvec(root_node, input)`` is called, step by step: + +1. The initial input is a string vector ``["foo bar"]``. +2. The *sh_lex* node splits the input as a shell would have done it, in + ``["foo", "bar"]``, and passes it to its child. +3. The *seq* node (sequence) passes the input to its first child. +4. The *str* node matches if the first element of the string vector is + ``foo``. This is the case, so it returns the number of eaten + strings (1) to its parent. +5. The *seq* node passes the remaining part ``["bar"]`` to its next + child. +6. The option node passes the string vector to its child, which + matches. It returns 1 to its parent. +7. The *seq* node has no more child, it returns the number of eaten + strings in the vector (2). +8. Finally, *sh_lex* compares the returned value to the number of + strings in its initial vector, and return 1 (match) to its caller. + +If a node does not match, it returns ``EC_PARSE_NOMATCH`` to its parent, +and it is propagated until it reaches a node that handle the case. For +instance, the *or* node is able to handle this error. If a child does +not match, the next one is tried until it finds one that matches. + +The parse tree +-------------- + +Let's take another simple example. + +.. figure:: simple-tree2.svg + + Another simple *ecoli grammar tree*. + +In that case, there is no lexer (the *sh_lex* node), so the input must +be a string vector that is already split. For instance, it matches: + +- ``["foo"]`` +- ``["bar", "1"]`` +- ``["bar", "100"]`` + +But it does **not** match: + +- ``["bar 1"]``, because there is no *sh_lex* node on the top of the tree +- ``["bar"]`` +- ``[]`` (empty vector) + +At the time the input is parsed, a *parse tree* is built. When it +matches, it describes which part of the *ecoli grammar tree* that +actually matched, and what input matched for each node. + +Passing ``["bar", "1"]`` to the previous tree would result in the +following *parse tree*: + +.. figure:: parse-tree.svg + + The *ecoli parse tree*, result of parsing. + +Each node of the *parse tree* references the node of the *grammar tree* +that matched. It also stores the string vector that matched. + +.. figure:: parse-tree2.svg + + The same *ecoli parse tree*, showing the references to the grammar + tree. + +We can see that not all of the grammar nodes are referenced, since the +str("foo") node was not parsed. Similarly, one grammar node can be +referenced several times in the parse tree, as we can see it in the +following example: + +.. figure:: simple-tree3.svg + + A simple *ecoli grammar tree*, that matches ``[]``, ``[foo]``, + ``[foo, foo]``, ... + +Here is the resulting *parse tree* when the input vector is ``[foo, foo, +foo]``: + +.. figure:: parse-tree3.svg + + The resulting *parse tree*. + +Node identifier +--------------- + +XXX + +Todo +---- + +- completions +- C example +- ec_config +- parse yaml +- params are consumed +- nodes +- attributes diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..657ac6f --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 Olivier Matz + +# -*- coding: utf-8 -*- +# +# Libecoli Documentation documentation build configuration file, created by +# sphinx-quickstart on Thu May 23 20:10:46 2019. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['breathe'] +import os +cautodoc_root = os.path.abspath('my/sources/dir') + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Libecoli Documentation' +copyright = u'2019, Olivier Matz' +author = u'Olivier Matz' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'0.1' +# The full version, including alpha/beta/rc tags. +release = u'0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +html_theme_options = { + 'sidebar_width': '350px', + 'logo': 'libecoli.svg', + 'fixed_sidebar': True, + 'page_width': '1200px', +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'LibecoliDocumentationdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'LibecoliDocumentation.tex', u'Libecoli Documentation Documentation', + u'Olivier Matz', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libecolidocumentation', u'Libecoli Documentation Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'LibecoliDocumentation', u'Libecoli Documentation Documentation', + author, 'LibecoliDocumentation', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/doc/contributing.rst b/doc/contributing.rst new file mode 100644 index 0000000..ab62905 --- /dev/null +++ b/doc/contributing.rst @@ -0,0 +1,7 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +Contributing +============ + +Todo. diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..a5f8731 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,45 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +Libecoli Documentation +====================== + +This is the documentation of *libecoli*. This library simplifies the +creation of interactive command line interfaces (*Ecoli* stands for +Extensible COmmand LIne). + +What can it be used for? + +- complex interactive cli interface in C (ex: a router cli) +- interactive cli for shell scripts +- application arguments parsing, natively supporting bash completion +- parsers + +What are the main features? + +- dynamic completion +- contextual help +- integrated with libedit, but can use any readline-like library +- modular: the cli behavior is defined through an assembly of basic + nodes +- extensible: the user can write its own nodes to provide specific + features +- C API +- YAML API and Shell API: used from shell scripts + +Who use it? + +- 6WIND_ for its Turbo Router cli + +.. _6WIND: https://www.6wind.com + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + overview + installation + user_guide + architecture + api + contributing diff --git a/doc/installation.rst b/doc/installation.rst new file mode 100644 index 0000000..edf0f4d --- /dev/null +++ b/doc/installation.rst @@ -0,0 +1,7 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +Installation +============ + +Todo. diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 0000000..a6c7028 --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019, Olivier MATZ + +doc_install_dir = join_paths('share', 'doc', 'libecoli') + +doxygen = find_program('doxygen', required : false) +if not doxygen.found() + error('MESON_SKIP_TEST doxygen not found.') +endif + +cdata = configuration_data() +cdata.set('VERSION', meson.project_version()) +cdata.set('OUTPUT', join_paths(meson.build_root(), 'doc', 'api')) +cdata.set('TOPDIR', meson.source_root()) + +doxygen_conf = configure_file( + input: 'Doxyfile.in', + output: 'Doxyfile', + configuration: cdata, + install: false) + +doxygen_build = custom_target( + 'doxygen', + input: doxygen_conf, + output: 'api', + command: [doxygen, '@INPUT@', '@OUTPUT@'], + build_by_default: true, + install_dir: doc_install_dir) + +sphinx_build = find_program( + 'sphinx-build', required: get_option('build_doc')) +if get_option('build_doc') and sphinx_build.found() + html_doc = custom_target('html_doc', + input: meson.current_source_dir(), + output: 'html_doc', + command: [sphinx_build, '@INPUT@', '@OUTPUT@'], + install: get_option('build_doc'), + install_dir: doc_install_dir) +endif diff --git a/doc/overview.rst b/doc/overview.rst new file mode 100644 index 0000000..2ac3cbe --- /dev/null +++ b/doc/overview.rst @@ -0,0 +1,7 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +Overview +======== + +Todo. diff --git a/doc/parse-tree.svg b/doc/parse-tree.svg new file mode 100644 index 0000000..9657a0a --- /dev/null +++ b/doc/parse-tree.svg @@ -0,0 +1,212 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + or + str + seq + + + + int + + [bar, 1] + [bar, 1] + [bar] + [1] + + diff --git a/doc/parse-tree2.svg b/doc/parse-tree2.svg new file mode 100644 index 0000000..5d22d6a --- /dev/null +++ b/doc/parse-tree2.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + or + str + seq + + + + int + + [bar, 1] + [bar, 1] + [bar] + [1] + + + + + + or + strfoo + strbar + seq + + + + + int + + + + + + + diff --git a/doc/parse-tree3.svg b/doc/parse-tree3.svg new file mode 100644 index 0000000..d779721 --- /dev/null +++ b/doc/parse-tree3.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + many + strfoo + + + many + str + + [foo, foo,foo] + [foo] + str + [foo] + + + + str + [foo] + + + + + + diff --git a/doc/simple-tree.svg b/doc/simple-tree.svg new file mode 100644 index 0000000..ef3863e --- /dev/null +++ b/doc/simple-tree.svg @@ -0,0 +1,204 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + sh_lex + seq + strfoo + strbar + option + + + + + + diff --git a/doc/simple-tree2.svg b/doc/simple-tree2.svg new file mode 100644 index 0000000..2269c88 --- /dev/null +++ b/doc/simple-tree2.svg @@ -0,0 +1,204 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + or + strfoo + strbar + seq + + + + + int + + + diff --git a/doc/simple-tree3.svg b/doc/simple-tree3.svg new file mode 100644 index 0000000..f3a9f4b --- /dev/null +++ b/doc/simple-tree3.svg @@ -0,0 +1,121 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + many + strfoo + + + diff --git a/doc/user_guide.rst b/doc/user_guide.rst new file mode 100644 index 0000000..0d58c8e --- /dev/null +++ b/doc/user_guide.rst @@ -0,0 +1,7 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 Olivier Matz + +User Guide +========== + +Todo. diff --git a/include/ecoli.h b/include/ecoli.h new file mode 100644 index 0000000..f5c42d2 --- /dev/null +++ b/include/ecoli.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2016, Olivier MATZ + */ + +/** + * @anchor main_page + * @mainpage About Libecoli + * + * This is the C API documentation of libecoli. This library provides + * helpers to build interactive command line interfaces. + * + * To create a command line parser, one should create a @ref + * grammar_tree, which is composed of @ref nodes. Then an input can be + * parsed or completed, respectively using the @ref parse and @ref + * complete APIs. + * + * The library also provides helpers to create a an interactive command + * line based on @ref editline library, and a @ref yaml parser for + * grammar trees. + */ + +#ifndef ECOLI_ +#define ECOLI_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/ecoli_assert.h b/include/ecoli_assert.h index fcd2186..c44dc14 100644 --- a/include/ecoli_assert.h +++ b/include/ecoli_assert.h @@ -3,7 +3,10 @@ */ /** - * Assert API + * @defgroup assert Assert + * @{ + * + * @brief Assertion helpers * * Helpers to check at runtime if a condition is true, or otherwise * either abort (exit program) or return an error. @@ -53,3 +56,5 @@ void __ec_assert_print(bool expr, const char *expr_str, } while(0) #endif + +/** @} */ diff --git a/include/ecoli_complete.h b/include/ecoli_complete.h index 4c71b5d..b28aa4a 100644 --- a/include/ecoli_complete.h +++ b/include/ecoli_complete.h @@ -3,12 +3,17 @@ */ /** - * API for generating completions item on a node. + * @defgroup complete Complete + * @{ + * + * @brief Complete string input using a grammar tree * * This file provide helpers to list and manipulate the possible * completions for a given input. * * XXX comp vs item + * + * @} */ #ifndef ECOLI_COMPLETE_ diff --git a/include/ecoli_config.h b/include/ecoli_config.h index b6d638e..ba93337 100644 --- a/include/ecoli_config.h +++ b/include/ecoli_config.h @@ -2,6 +2,13 @@ * Copyright 2018, Olivier MATZ */ +/** + * @defgroup config Node configuration + * @{ + * + * @brief Configure nodes behavior through generic API. + */ + #ifndef ECOLI_CONFIG_ #define ECOLI_CONFIG_ @@ -402,3 +409,5 @@ ec_config_dup(const struct ec_config *config); void ec_config_dump(FILE *out, const struct ec_config *config); #endif + +/** @} */ diff --git a/include/ecoli_dict.h b/include/ecoli_dict.h index 77558fb..b4bf780 100644 --- a/include/ecoli_dict.h +++ b/include/ecoli_dict.h @@ -3,7 +3,10 @@ */ /** - * Simple hash table API + * @defgroup dict Dictionary + * @{ + * + * @brief Simple hash table API (string keys) * * This file provides functions to store objects in hash tables, using strings * as keys. @@ -184,3 +187,5 @@ void * ec_dict_iter_get_val(const struct ec_dict_elt_ref *iter); #endif + +/** @} */ diff --git a/include/ecoli_editline.h b/include/ecoli_editline.h index 58824d2..414d58b 100644 --- a/include/ecoli_editline.h +++ b/include/ecoli_editline.h @@ -3,6 +3,11 @@ */ /** + * @defgroup editline Editline + * @{ + * + * @brief Helpers for editline + * * Helpers that can be used to associate an editline instance with * an ecoli node tree. * diff --git a/include/ecoli_htable.h b/include/ecoli_htable.h index 0bed676..3e9eab9 100644 --- a/include/ecoli_htable.h +++ b/include/ecoli_htable.h @@ -3,7 +3,10 @@ */ /** - * Simple hash table API + * @defgroup htable Hash table + * @{ + * + * @brief Simple hash table API (any key) * * This file provides functions to store objects in hash tables, * using arbitrary data as keys. @@ -206,3 +209,5 @@ void * ec_htable_iter_get_val(const struct ec_htable_elt_ref *iter); #endif + +/** @} */ diff --git a/include/ecoli_init.h b/include/ecoli_init.h index 80a0c01..39938f7 100644 --- a/include/ecoli_init.h +++ b/include/ecoli_init.h @@ -3,7 +3,10 @@ */ /** - * Register initialization routines. + * @defgroup nodes Nodes + * @{ + * + * @brief Register initialization routines. */ #ifndef ECOLI_INIT_ @@ -74,3 +77,5 @@ int ec_init(void); void ec_exit(void); #endif + +/** @} */ diff --git a/include/ecoli_log.h b/include/ecoli_log.h index bc18f96..9363d23 100644 --- a/include/ecoli_log.h +++ b/include/ecoli_log.h @@ -3,7 +3,10 @@ */ /** - * Logging API + * @defgroup log Log + * @{ + * + * @brief Log API * * This file provide logging helpers: * - logging functions, supporting printf-like format @@ -237,3 +240,5 @@ int ec_log_level_set(enum ec_log_level level); enum ec_log_level ec_log_level_get(void); #endif + +/** @} */ diff --git a/include/ecoli_malloc.h b/include/ecoli_malloc.h index 42cbf87..0e5d2ba 100644 --- a/include/ecoli_malloc.h +++ b/include/ecoli_malloc.h @@ -3,6 +3,11 @@ */ /** + * @defgroup alloc Allocation + * @{ + * + * @brief Helpers to allocate and free memory + * * Interface to configure the allocator used by libecoli. * By default, the standard allocation functions from libc are used. */ @@ -253,3 +258,5 @@ char *__ec_strndup(const char *s, size_t n, const char *file, #endif + +/** @} */ diff --git a/include/ecoli_murmurhash.h b/include/ecoli_murmurhash.h index 6b76d34..2cfd292 100644 --- a/include/ecoli_murmurhash.h +++ b/include/ecoli_murmurhash.h @@ -3,6 +3,11 @@ */ /** + * @defgroup murmurhash Murmurhash + * @{ + * + * @brief Hash calculation using murmurhash algorithm + * * MurmurHash3 is a hash implementation that was written by Austin Appleby, and * is placed in the public domain. The author hereby disclaims copyright to this * source code. @@ -64,3 +69,5 @@ static inline uint32_t ec_murmurhash3_fmix32(uint32_t h) uint32_t ec_murmurhash3(const void *key, int len, uint32_t seed); #endif /* ECOLI_MURMURHASH_H_ */ + +/** @} */ diff --git a/include/ecoli_node.h b/include/ecoli_node.h index acd1daa..894e64f 100644 --- a/include/ecoli_node.h +++ b/include/ecoli_node.h @@ -3,10 +3,13 @@ */ /** - * Interface to manage the ecoli nodes. + * @defgroup grammar_tree Grammar Tree + * @{ * - * A node is a main structure of the ecoli library, used to define how - * to match and complete the input tokens. A node is a generic object + * @brief Libecoli grammar nodes. + * + * The grammar node is a main structure of the ecoli library, used to define + * how to match and complete the input tokens. A node is a generic object * that implements: * - a parse(node, input) method: check if an input matches * - a complete(node, input) method: return possible completions for @@ -46,6 +49,9 @@ #include #include +/** + * Node has no identifier. + */ #define EC_NO_ID "no-id" #define EC_NODE_ENDLIST ((void *)1) @@ -204,3 +210,5 @@ int ec_node_check_type(const struct ec_node *node, const struct ec_node_type *type); #endif + + /** @} */ diff --git a/include/ecoli_node_any.h b/include/ecoli_node_any.h index cb671e3..3f21927 100644 --- a/include/ecoli_node_any.h +++ b/include/ecoli_node_any.h @@ -3,6 +3,9 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * This node always matches 1 string in the vector. * An optional strvec attribute can be checked too. These * attributes are usually set by a lexer node. @@ -25,3 +28,5 @@ struct ec_node * ec_node_any(const char *id, const char *attr); #endif + +/** @} */ diff --git a/include/ecoli_node_bypass.h b/include/ecoli_node_bypass.h index a5efb46..024bcae 100644 --- a/include/ecoli_node_bypass.h +++ b/include/ecoli_node_bypass.h @@ -3,6 +3,9 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * A node that does nothing else than calling the child node. * It can be helpful to build loops in a node graph. */ @@ -16,3 +19,5 @@ struct ec_node *ec_node_bypass(const char *id, struct ec_node *node); int ec_node_bypass_set_child(struct ec_node *gen_node, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_cmd.h b/include/ecoli_node_cmd.h index 99afc01..a605492 100644 --- a/include/ecoli_node_cmd.h +++ b/include/ecoli_node_cmd.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_CMD_ #define ECOLI_NODE_CMD_ @@ -12,3 +17,5 @@ struct ec_node *__ec_node_cmd(const char *id, const char *cmd_str, ...); #endif + +/** @} */ diff --git a/include/ecoli_node_cond.h b/include/ecoli_node_cond.h index 37da1a4..83f7d4e 100644 --- a/include/ecoli_node_cond.h +++ b/include/ecoli_node_cond.h @@ -3,6 +3,9 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * The condition node checks that an expression is true before * parsing/completing the child node. If it is false, the node * doesn't match anything. @@ -29,3 +32,5 @@ struct ec_node *ec_node_cond(const char *id, const char *cond_str, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_dynamic.h b/include/ecoli_node_dynamic.h index 4f2535e..65d3085 100644 --- a/include/ecoli_node_dynamic.h +++ b/include/ecoli_node_dynamic.h @@ -2,6 +2,11 @@ * Copyright 2017, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_DYNAMIC_ #define ECOLI_NODE_DYNAMIC_ @@ -17,3 +22,5 @@ struct ec_node *ec_node_dynamic(const char *id, ec_node_dynamic_build_t build, void *opaque); #endif + +/** @} */ diff --git a/include/ecoli_node_empty.h b/include/ecoli_node_empty.h index ed5e32e..bfafc9b 100644 --- a/include/ecoli_node_empty.h +++ b/include/ecoli_node_empty.h @@ -3,6 +3,9 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * This node always matches an empty string vector */ @@ -12,3 +15,5 @@ struct ec_node *ec_node_empty(const char *id); #endif + +/** @} */ diff --git a/include/ecoli_node_expr.h b/include/ecoli_node_expr.h index 4f21d81..15f81ae 100644 --- a/include/ecoli_node_expr.h +++ b/include/ecoli_node_expr.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_EXPR_ #define ECOLI_NODE_EXPR_ @@ -91,3 +96,5 @@ int ec_node_expr_eval(void **result, const struct ec_node *node, void *userctx); #endif + +/** @} */ diff --git a/include/ecoli_node_file.h b/include/ecoli_node_file.h index 5760902..cadad83 100644 --- a/include/ecoli_node_file.h +++ b/include/ecoli_node_file.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_FILE_ #define ECOLI_NODE_FILE_ @@ -13,3 +18,5 @@ struct ec_node *ec_node_file(const char *id, const char *file); int ec_node_file_set_str(struct ec_node *node, const char *file); #endif + +/** @} */ diff --git a/include/ecoli_node_int.h b/include/ecoli_node_int.h index b64c60c..6fac1c1 100644 --- a/include/ecoli_node_int.h +++ b/include/ecoli_node_int.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_INT_ #define ECOLI_NODE_INT_ @@ -26,5 +31,6 @@ struct ec_node *ec_node_uint(const char *id, uint64_t min, int ec_node_uint_getval(const struct ec_node *node, const char *str, uint64_t *result); - #endif + +/** @} */ diff --git a/include/ecoli_node_many.h b/include/ecoli_node_many.h index 0a50fd7..bc31542 100644 --- a/include/ecoli_node_many.h +++ b/include/ecoli_node_many.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_MANY_ #define ECOLI_NODE_MANY_ @@ -16,3 +21,5 @@ ec_node_many_set_params(struct ec_node *gen_node, struct ec_node *child, unsigned int min, unsigned int max); #endif + +/** @} */ diff --git a/include/ecoli_node_none.h b/include/ecoli_node_none.h index 842f211..b5e368e 100644 --- a/include/ecoli_node_none.h +++ b/include/ecoli_node_none.h @@ -3,10 +3,15 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * This node does not match anything */ -#ifndef ECOLI_NODE_ANY_ -#define ECOLI_NODE_ANY_ +#ifndef ECOLI_NODE_NONE_ +#define ECOLI_NODE_NONE_ #endif + +/** @} */ diff --git a/include/ecoli_node_once.h b/include/ecoli_node_once.h index 690a10c..3e05525 100644 --- a/include/ecoli_node_once.h +++ b/include/ecoli_node_once.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_ONCE_ #define ECOLI_NODE_ONCE_ @@ -27,3 +32,5 @@ struct ec_node *ec_node_once(const char *id, struct ec_node *child); int ec_node_once_set_child(struct ec_node *node, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_option.h b/include/ecoli_node_option.h index 9f06d5f..c88fb23 100644 --- a/include/ecoli_node_option.h +++ b/include/ecoli_node_option.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_OPTION_ #define ECOLI_NODE_OPTION_ @@ -11,3 +16,5 @@ struct ec_node *ec_node_option(const char *id, struct ec_node *node); int ec_node_option_set_child(struct ec_node *gen_node, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_or.h b/include/ecoli_node_or.h index db115b2..1738af1 100644 --- a/include/ecoli_node_or.h +++ b/include/ecoli_node_or.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_OR_ #define ECOLI_NODE_OR_ @@ -20,5 +25,6 @@ struct ec_node *ec_node_or(const char *id); /* child is consumed */ int ec_node_or_add(struct ec_node *node, struct ec_node *child); - #endif + +/** @} */ diff --git a/include/ecoli_node_re.h b/include/ecoli_node_re.h index bc3a317..66957c7 100644 --- a/include/ecoli_node_re.h +++ b/include/ecoli_node_re.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_RE_ #define ECOLI_NODE_RE_ @@ -13,3 +18,5 @@ struct ec_node *ec_node_re(const char *id, const char *str); int ec_node_re_set_regexp(struct ec_node *node, const char *re); #endif + +/** @} */ diff --git a/include/ecoli_node_re_lex.h b/include/ecoli_node_re_lex.h index 94d426e..c6aea65 100644 --- a/include/ecoli_node_re_lex.h +++ b/include/ecoli_node_re_lex.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_RE_LEX_ #define ECOLI_NODE_RE_LEX_ @@ -13,3 +18,5 @@ int ec_node_re_lex_add(struct ec_node *gen_node, const char *pattern, int keep, const char *attr_name); #endif + +/** @} */ diff --git a/include/ecoli_node_seq.h b/include/ecoli_node_seq.h index 21c96b1..e1f3896 100644 --- a/include/ecoli_node_seq.h +++ b/include/ecoli_node_seq.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_SEQ_ #define ECOLI_NODE_SEQ_ @@ -21,3 +26,5 @@ struct ec_node *ec_node_seq(const char *id); int ec_node_seq_add(struct ec_node *node, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_sh_lex.h b/include/ecoli_node_sh_lex.h index d45b998..bbe2505 100644 --- a/include/ecoli_node_sh_lex.h +++ b/include/ecoli_node_sh_lex.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_SHLEX_ #define ECOLI_NODE_SHLEX_ @@ -10,3 +15,5 @@ struct ec_node *ec_node_sh_lex(const char *id, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_node_space.h b/include/ecoli_node_space.h index 0dd6202..bb4dac9 100644 --- a/include/ecoli_node_space.h +++ b/include/ecoli_node_space.h @@ -3,6 +3,9 @@ */ /** + * @defgroup nodes Nodes + * @{ + * * This node matches one string in the vector if it is only composed of * spaces, as interpreted by isspace(). */ @@ -13,3 +16,5 @@ /* no API for now, since there is no specific configuration for this node */ #endif + +/** @} */ diff --git a/include/ecoli_node_str.h b/include/ecoli_node_str.h index 8a8634f..de2454f 100644 --- a/include/ecoli_node_str.h +++ b/include/ecoli_node_str.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_STR_ #define ECOLI_NODE_STR_ @@ -13,3 +18,5 @@ struct ec_node *ec_node_str(const char *id, const char *str); int ec_node_str_set_str(struct ec_node *node, const char *str); #endif + +/** @} */ diff --git a/include/ecoli_node_subset.h b/include/ecoli_node_subset.h index 734b1ae..6ec3319 100644 --- a/include/ecoli_node_subset.h +++ b/include/ecoli_node_subset.h @@ -2,6 +2,11 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup nodes Nodes + * @{ + */ + #ifndef ECOLI_NODE_SUBSET_ #define ECOLI_NODE_SUBSET_ @@ -21,3 +26,5 @@ struct ec_node *ec_node_subset(const char *id); int ec_node_subset_add(struct ec_node *node, struct ec_node *child); #endif + +/** @} */ diff --git a/include/ecoli_parse.h b/include/ecoli_parse.h index c88fc18..a64c0ae 100644 --- a/include/ecoli_parse.h +++ b/include/ecoli_parse.h @@ -3,11 +3,18 @@ */ /** + * @defgroup parse Parse + * @{ + * + * @brief Create parse tree from string input and grammar tree + * * Node parse API. * * The parse operation is to check if an input (a string or vector of * strings) matches the node tree. On success, the result is stored in a * tree that describes which part of the input matches which node. + * + * @} */ #ifndef ECOLI_PARSE_ diff --git a/include/ecoli_string.h b/include/ecoli_string.h index d611a13..3ef022c 100644 --- a/include/ecoli_string.h +++ b/include/ecoli_string.h @@ -2,6 +2,13 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup string String + * @{ + * + * @brief Helpers for strings manipulation. + */ + #ifndef ECOLI_STRING_ #define ECOLI_STRING_ diff --git a/include/ecoli_strvec.h b/include/ecoli_strvec.h index 727d4c8..2464a2b 100644 --- a/include/ecoli_strvec.h +++ b/include/ecoli_strvec.h @@ -3,7 +3,10 @@ */ /** - * Vectors of strings. + * @defgroup strvec String vectors + * @{ + * + * @brief Helpers for strings vectors manipulation. * * The ec_strvec API provide helpers to manipulate string vectors. * When duplicating vectors, the strings are not duplicated in memory, @@ -222,3 +225,5 @@ void ec_strvec_sort(struct ec_strvec *strvec, void ec_strvec_dump(FILE *out, const struct ec_strvec *strvec); #endif + +/** } */ diff --git a/include/ecoli_test.h b/include/ecoli_test.h index 94cd0b9..e4b091b 100644 --- a/include/ecoli_test.h +++ b/include/ecoli_test.h @@ -2,6 +2,13 @@ * Copyright 2016, Olivier MATZ */ +/** + * @defgroup test Test + * @{ + * + * @brief Helpers for unit tests + */ + #ifndef ECOLI_TEST_ #define ECOLI_TEST_ @@ -95,3 +102,5 @@ int ec_test_check_complete(struct ec_node *node, }) #endif + +/** @} */ diff --git a/include/ecoli_utils.h b/include/ecoli_utils.h index 5a14192..98bfcc9 100644 --- a/include/ecoli_utils.h +++ b/include/ecoli_utils.h @@ -2,6 +2,14 @@ * Copyright 2018, Olivier MATZ */ +/** + * @defgroup utils Utils + * @{ + * + * @brief Misc utils + */ + + #ifndef ECOLI_UTILS_ #define ECOLI_UTILS_ @@ -14,3 +22,5 @@ }) #endif + +/** @} */ diff --git a/include/ecoli_vec.h b/include/ecoli_vec.h index 5fdaa99..784d440 100644 --- a/include/ecoli_vec.h +++ b/include/ecoli_vec.h @@ -3,7 +3,10 @@ */ /** - * Vectors of objects. + * @defgroup vec Vectors + * @{ + * + * @brief Helpers for vectors manipulation. * * The ec_vec API provide helpers to manipulate vectors of objects * of any kind. @@ -45,3 +48,5 @@ __attribute__((pure)) size_t ec_vec_len(const struct ec_vec *vec); #endif + +/** @} */ diff --git a/include/ecoli_yaml.h b/include/ecoli_yaml.h index a63d837..6d26bbc 100644 --- a/include/ecoli_yaml.h +++ b/include/ecoli_yaml.h @@ -3,6 +3,11 @@ */ /** + * @defgroup yaml Yaml + * @{ + * + * @brief YAML import/export + * * Interface to import/export ecoli data structures in YAML. */ @@ -23,3 +28,5 @@ struct ec_node; struct ec_node *ec_yaml_import(const char *filename); #endif + +/** } */ diff --git a/include/meson.build b/include/meson.build index 1b97922..b7eeb60 100644 --- a/include/meson.build +++ b/include/meson.build @@ -2,6 +2,7 @@ # Copyright 2018, Olivier MATZ libecoli_headers = [ + 'ecoli.h', 'ecoli_assert.h', 'ecoli_complete.h', 'ecoli_config.h', diff --git a/meson.build b/meson.build index 0e7ebb0..ca9ddf1 100644 --- a/meson.build +++ b/meson.build @@ -19,6 +19,7 @@ priv_inc = include_directories('src') subdir('src') subdir('test') subdir('examples') +subdir('doc') pkg_mod = import('pkgconfig') pkg_mod.generate(libraries : libecoli, -- 2.20.1