From 158a626249b80cd081c0159106bb9100a30bb059 Mon Sep 17 00:00:00 2001 From: Tom Huang Date: Sat, 27 Apr 2024 17:33:23 -0700 Subject: [PATCH] docs: use new sphinx file structure --- .gitignore | 3 + Makefile | 10 +- README.md | 32 +++- docs/Doxyfile | 2 +- docs/Makefile | 4 +- docs/_static/custom.css | 3 - docs/conf.py | 76 --------- docs/index.rst | 198 ----------------------- docs/make.bat | 10 +- docs/source/_static/custom.css | 1 + docs/{ => source}/_templates/footer.html | 0 docs/source/arg_api_deprecated.md | 4 + docs/source/arg_api_dyna_string.md | 1 + docs/source/arg_api_output.md | 7 + docs/source/arg_api_parsing.md | 117 ++++++++++++++ docs/source/arg_api_subcommand.md | 1 + docs/source/arg_dev_build.md | 1 + docs/source/arg_dev_docs.md | 133 +++++++++++++++ docs/source/arg_dev_internals.md | 1 + docs/source/arg_dev_tests.md | 1 + docs/source/arg_getting_started.md | 97 +++++++++++ docs/source/arg_installation.md | 173 ++++++++++++++++++++ docs/source/assets/doc-gen-flow.png | Bin 0 -> 23858 bytes docs/source/conf.py | 43 +++++ docs/source/index.md | 195 ++++++++++++++++++++++ 25 files changed, 817 insertions(+), 296 deletions(-) delete mode 100644 docs/_static/custom.css delete mode 100644 docs/conf.py delete mode 100644 docs/index.rst create mode 100644 docs/source/_static/custom.css rename docs/{ => source}/_templates/footer.html (100%) create mode 100644 docs/source/arg_api_deprecated.md create mode 100644 docs/source/arg_api_dyna_string.md create mode 100644 docs/source/arg_api_output.md create mode 100644 docs/source/arg_api_parsing.md create mode 100644 docs/source/arg_api_subcommand.md create mode 100644 docs/source/arg_dev_build.md create mode 100644 docs/source/arg_dev_docs.md create mode 100644 docs/source/arg_dev_internals.md create mode 100644 docs/source/arg_dev_tests.md create mode 100644 docs/source/arg_getting_started.md create mode 100644 docs/source/arg_installation.md create mode 100644 docs/source/assets/doc-gen-flow.png create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.md diff --git a/.gitignore b/.gitignore index 83c1372..733cc65 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ dist/ .archive/ .tags/ .misc/ +.py*/ +docs/source/xml/ +docs/build/ # Ignore JetBrains and Eclipse IDE metadata and default build directories .vscode/ diff --git a/Makefile b/Makefile index c004786..0785d7f 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,11 @@ MKINDEX = makeindex PRINTF = printf GIT = git -BUILD_DIR = build -ARCHIVE_DIR = .archive -TAGS_DIR = .tags +BUILD_DIR = build +DOXYGEN_XML_DIR = docs/source/xml +DOCS_BUILD_DIR = docs/build +ARCHIVE_DIR = .archive +TAGS_DIR = .tags MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) MAKEFILE_DIR := $(abspath $(dir $(MAKEFILE_PATH))) @@ -112,6 +114,8 @@ taglist: cleanall: @$(PRINTF) "Clean the distribution package and temp files...\n" @$(RM) $(BUILD_DIR) + @$(RM) $(DOXYGEN_XML_DIR) + @$(RM) $(DOCS_BUILD_DIR) .PHONY: githead diff --git a/README.md b/README.md index 31376c2..126652d 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ amalgamation distribution under the build directory. Documentation ------------- -To learn how to use the Argtable3 API, you can see the documentation on the web +To learn how to use the Argtable3 API, you can read the documentation on the web site, study examples in the `examples` directory, or even check the unit tests in the `tests` directory. @@ -199,24 +199,40 @@ tools: * [Sphinx](https://www.sphinx-doc.org): A documentation generator based on the reStructuredText markup format. -* [Read the Docs Sphinx Theme](https://sphinx-rtd-theme.readthedocs.io): A - Sphinx theme designed to look modern and be mobile-friendly. +* [Furo Theme](https://pradyunsg.me/furo/quickstart/): A Sphinx theme designed + to look modern and be mobile-friendly. * [Breathe](https://breathe.readthedocs.io): A bridge between the Sphinx and Doxygen documentation systems. * [Doxygen](http://www.doxygen.nl/): A documentation generator for C/C++ sources. +* [MyST Parser](https://myst-parser.readthedocs.io): A Sphinx extension to parse + MyST, a rich and extensible flavour of Markdown for authoring technical and + scientific documentation. -Go to the `docs` directory and run the `doxygen` command to generate Doxygen XML -output, which will be saved in the `docs/xml` directory: +Except Doxygen, all the document generation tools are Python-based, so you can +install the tools in a Python virtual environment: ``` -$ doxygen +$ python --version +Python 3.11.5 + +$ python -m venv .py311 +$ .py311\Scripts\activate.bat + +(.py311) $ pip install --upgrade sphinx +(.py311) $ pip install --upgrade furo +(.py311) $ pip install --upgrade breathe +(.py311) $ pip install --upgrade myst-parser ``` -Run the `make` batch script and you will see the documentation in the -`docs/_build/html` directory. +After installing the tools, go to the `docs` directory and run the `doxygen` +command to generate the Doxygen XML output, which should be generated in the +`docs/source/xml` directory. Finally, run `make html` to generate the +documentation in the `docs/build/html` directory. ``` +$ cd docs +$ doxygen $ make html ``` diff --git a/docs/Doxyfile b/docs/Doxyfile index 5580393..7a86924 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,5 +1,5 @@ PROJECT_NAME = "argtable" -XML_OUTPUT = xml +XML_OUTPUT = source/xml INPUT = ../src GENERATE_LATEX = NO GENERATE_MAN = NO diff --git a/docs/Makefile b/docs/Makefile index d4bb2cb..d0c3cbf 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,8 +5,8 @@ # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build +SOURCEDIR = source +BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: diff --git a/docs/_static/custom.css b/docs/_static/custom.css deleted file mode 100644 index 8cb4a30..0000000 --- a/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -.wy-nav-content { - max-width: none; -} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 9d9bc3e..0000000 --- a/docs/conf.py +++ /dev/null @@ -1,76 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# 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, 'C:/Bin/Python35/Lib/site-packages/breathe') - - -# -- Project information ----------------------------------------------------- - -project = 'Argtable' -copyright = '2020, Argtable Project members and individual contributors' -author = 'Tom G. Huang' - -# The full version, including alpha/beta/rc tags -release = '3.1.5' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx_rtd_theme", - "breathe", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# 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 = 'c' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -import sphinx_rtd_theme - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# 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'] - -# html_css_files = [ -# 'custom.css', -# ] - - -# -- Options for Breathe extension ------------------------------------------- - -breathe_projects = { "argtable": 'D:/Projects/argtable3/docs/xml' } -breathe_default_project = "argtable" diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index ceb01ab..0000000 --- a/docs/index.rst +++ /dev/null @@ -1,198 +0,0 @@ -.. Copyright(c) 2020, Tom G. Huang - https://xtensor.readthedocs.io/en/latest/index.html - https://github.com/xtensor-stack/xtensor/tree/master/docs/source - https://fmt.dev/latest/index.html - https://github.com/fmtlib/fmt/tree/master/doc - https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html# - https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/ - https://docs.zephyrproject.org/latest/ - https://github.com/zephyrproject-rtos/zephyr/tree/master/doc - https://gist.github.com/dupuy/1855764 - -Introduction -============ - -Argtable is an open source ANSI C library that parses GNU-style command-line -options. It simplifies command-line parsing by defining a declarative-style API -that you can use to specify what your command-line syntax looks like. Argtable -will automatically generate consistent error handling logic and textual -descriptions of the command line syntax, which are essential but tedious to -implement for a robust CLI program. For example, to create a CLI program that -looks like: - -.. code:: shell - - $ util.exe --help - Usage: util.exe [-v] [--help] [--version] [--level=] [-o myfile] []... - Demonstrate command-line parsing in argtable3. - - --help display this help and exit - --version display version information and exit - --level= foo value - -v, --verbose verbose output - -o myfile output file - input files - - -.. note:: - - This documentation is for the latest Argtable **v3 series**, which is derived - from Argtable v2 series created by `Stewart Heitmann - `_. **Argtable3 is not - backward-compatible**. Therefore, if you want to use Argtable2 API, you have - to go to the `Argtable2 web site `_ and get - the source code from its `Sourceforge.net project page - `_. - - -You can implement the command-line parsing logic with Argtable in the following code snippet: - -.. code:: c - - #include "argtable3.h" - - /* global arg_xxx structs */ - struct arg_lit *verb, *help, *version; - struct arg_int *level; - struct arg_file *o, *file; - struct arg_end *end; - - int main(int argc, char *argv[]) - { - /* the global arg_xxx structs are initialised within the argtable */ - void *argtable[] = { - help = arg_litn(NULL, "help", 0, 1, "display this help and exit"), - version = arg_litn(NULL, "version", 0, 1, "display version info and exit"), - level = arg_intn(NULL, "level", "", 0, 1, "foo value"), - verb = arg_litn("v", "verbose", 0, 1, "verbose output"), - o = arg_filen("o", NULL, "myfile", 0, 1, "output file"), - file = arg_filen(NULL, NULL, "", 1, 100, "input files"), - end = arg_end(20), - }; - - int exitcode = 0; - char progname[] = "util.exe"; - - int nerrors; - nerrors = arg_parse(argc,argv,argtable); - - /* special case: '--help' takes precedence over error reporting */ - if (help->count > 0) - { - printf("Usage: %s", progname); - arg_print_syntax(stdout, argtable, "\n"); - printf("Demonstrate command-line parsing in argtable3.\n\n"); - arg_print_glossary(stdout, argtable, " %-25s %s\n"); - exitcode = 0; - goto exit; - } - - /* If the parser returned any errors then display them and exit */ - if (nerrors > 0) - { - /* Display the error details contained in the arg_end struct.*/ - arg_print_errors(stdout, end, progname); - printf("Try '%s --help' for more information.\n", progname); - exitcode = 1; - goto exit; - } - - exit: - /* deallocate each non-null entry in argtable[] */ - arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); - return exitcode; - } - - -Features --------- - -Here is a list of reasons why you should include Argtable in your C/C++ toolbox: - -* **GNU-style command-line syntax**: Use the standard and cross-platform way to express commands. -* **Declarative API**: Eliminate complex parsing logic by specifying what instead of elaborating how. -* **Built-in error handling**: Generate consistent error handling logic. -* **Built-in help messages**: Generate consistent command-line syntax descriptions. -* **Written in ANSI C**: Easy to create bindings for other languages. -* **Readable source code**: Well-commented source code with 100% branch test coverage. -* **Single-file library**: No tedious build scripts. Just drop a single source file into your projects. -* **Self-contained**: No external dependencies. -* **Cross-platform**: Available on most UNIX-like systems, Windows, and embedded systems. -* **BSD-licensed**: Use the library for any purpose, including in commercial programs. - - -What’s Next ------------ - -If you want to learn how to use Argtable3, you can start from the tutorial. If -you want to learn from examples, you can check a list of sample programs in the -repository. And if you find any issue of the documentation or code, you can -submit an issue to the Github project page. - -CLI programs have become more and more important in the cloud computing era. We -hope that Argtable can contribute to the Renaissance of CLI and help to make -both developers’ and users’ life easier. - - -Acknowledgements ----------------- - -* *Stewart Heitmann* for creating the original argtable-1.x and argtable-2.x libraries. -* *Nina Clemson* for editing the original argtable-1.0 documentation. -* *Livio Bertacco* for contributing bug fixes and the argtable-2.x Visual C++ Makefiles. -* *Justin Dearing* for contributing bug fixes and Windows DLL support, plus code support for the Open Watcom compiler and help with the Mac OS X configuration. -* *Asa Packer* for contributing bug fixes and upgrades to the Visual C++ Makefiles. -* *Danilo Cicerone* for the Italian translation of “Introduction to Argtable-2x” and the argtable devpak. -* *Uli Fouquet* for configuration patches and documentation related to cross-compiling argtable from Unix to Windows as well as providing the arg_print_glossary_gnu function. -* *Shachar Schemesh* for integrating argtable into Debian Linux and kick-starting the migration to automake/autoconf. -* *Jasper Lievisse Adriaanse* for maintaining the argtable package in OpenBSD ports. -* *Ulrich Mohr* for bug fixes relating to Texas Instrument DSP platforms. -* *John Vickers* and *Steve O’Neil* for bug fixes relating to Solaris/Motorola platforms. -* *Lori A. Pritchett-Sheats* for fixing a makefile bug relating to “make dist”. -* *Paolo Bormida* for instructions on building argtable with date and regex support on Windows. -* *Michel Valin* for bug fixes relating to the configure scripts on IBM AIX platforms and instructions on compiling the example code under AIX. -* *Steve Christensen* for providing prebuilt packages for SPARC/Solaris and x86/Solaris platforms on www.sunfreeware.com. -* *Jess Portnoy* for reworking the rpm package and integrating argtable into Fedora Linux. -* *Michael Brown* for incorporating support for pkg-config into the autoconf scripts. -* *Alexander Lindert* for extensions to the parser to support hex, octal and binary integer formats as well as KB/MB/GB suffixes. -* *Rob Zaborowski* for providing build configuration files for the CMake tool. -* *Moczik Gabor* for bug fixes relating to the parsing of filepaths and filename extensions. -* *Hanspeter Niederstrasser* for including the argtable package in FinkProject for Mac OS X. - - -.. toctree:: - :caption: INSTALLATION - :maxdepth: 1 - - arg_installation - arg_changelog - -.. toctree:: - :caption: USAGE - :maxdepth: 1 - - arg_getting_started -.. multi_commands -.. custom_format -.. regex -.. tcl -.. alias -.. configuration - -.. toctree:: - :caption: API REFERENCE - :maxdepth: 1 - - arg_api_parsing - arg_api_output - arg_api_dyna_string - arg_api_subcommand - arg_api_deprecated - -.. toctree:: - :caption: DEVELOPER ZONE - :maxdepth: 1 - - arg_dev_build - arg_dev_internals - arg_dev_tests \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat index 2119f51..747ffb7 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -7,10 +7,8 @@ REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help +set SOURCEDIR=source +set BUILDDIR=build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( @@ -21,10 +19,12 @@ if errorlevel 9009 ( echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) +if "%1" == "" goto help + %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 0000000..ed2d1fd --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1 @@ +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap'); diff --git a/docs/_templates/footer.html b/docs/source/_templates/footer.html similarity index 100% rename from docs/_templates/footer.html rename to docs/source/_templates/footer.html diff --git a/docs/source/arg_api_deprecated.md b/docs/source/arg_api_deprecated.md new file mode 100644 index 0000000..e84abba --- /dev/null +++ b/docs/source/arg_api_deprecated.md @@ -0,0 +1,4 @@ +# Deprecated + +:::{doxygenfunction} arg_free +::: diff --git a/docs/source/arg_api_dyna_string.md b/docs/source/arg_api_dyna_string.md new file mode 100644 index 0000000..4f6ab77 --- /dev/null +++ b/docs/source/arg_api_dyna_string.md @@ -0,0 +1 @@ +# Dynamic String diff --git a/docs/source/arg_api_output.md b/docs/source/arg_api_output.md new file mode 100644 index 0000000..5026013 --- /dev/null +++ b/docs/source/arg_api_output.md @@ -0,0 +1,7 @@ +# Output + +:::{doxygenstruct} arg_hdr +::: + +:::{doxygenstruct} arg_dbl +::: \ No newline at end of file diff --git a/docs/source/arg_api_parsing.md b/docs/source/arg_api_parsing.md new file mode 100644 index 0000000..b8f9f49 --- /dev/null +++ b/docs/source/arg_api_parsing.md @@ -0,0 +1,117 @@ +# Parsing + +:::{doxygenfunction} arg_parse +::: + +:::{doxygenfunction} arg_nullcheck +::: + +:::{doxygenfunction} arg_end +::: + +:::{doxygenfunction} arg_freetable +::: + + +## Boolean Options + +:::{doxygenfunction} arg_lit0 +:outline: +::: + +:::{doxygenfunction} arg_lit1 +:outline: +::: + +:::{doxygenfunction} arg_litn +::: + + +## Integer Options + +:::{doxygenfunction} arg_int0 +:outline: +::: + +:::{doxygenfunction} arg_int1 +:outline: +::: + +:::{doxygenfunction} arg_intn +::: + + +## Double Options + +:::{doxygenfunction} arg_dbl0 +:outline: +::: + +:::{doxygenfunction} arg_dbl1 +:outline: +::: + +:::{doxygenfunction} arg_dbln +::: + + +## String Options + +:::{doxygenfunction} arg_str0 +:outline: +::: + +:::{doxygenfunction} arg_str1 +:outline: +::: + +:::{doxygenfunction} arg_strn +::: + + +## Regex Options + +:::{doxygenfunction} arg_rex0 +:outline: +::: + +:::{doxygenfunction} arg_rex1 +:outline: +::: + +:::{doxygenfunction} arg_rexn +::: + + +## File Options + +:::{doxygenfunction} arg_file0 +:outline: +::: + +:::{doxygenfunction} arg_file1 +:outline: +::: + +:::{doxygenfunction} arg_filen +::: + + +## Date Options + +:::{doxygenfunction} arg_date0 +:outline: +::: + +:::{doxygenfunction} arg_date1 +:outline: +::: + +:::{doxygenfunction} arg_daten +::: + + +## Misc + +:::{doxygenfunction} arg_rem +::: diff --git a/docs/source/arg_api_subcommand.md b/docs/source/arg_api_subcommand.md new file mode 100644 index 0000000..ef72e49 --- /dev/null +++ b/docs/source/arg_api_subcommand.md @@ -0,0 +1 @@ +# Sub-Command Management diff --git a/docs/source/arg_dev_build.md b/docs/source/arg_dev_build.md new file mode 100644 index 0000000..a94f38c --- /dev/null +++ b/docs/source/arg_dev_build.md @@ -0,0 +1 @@ +# Build diff --git a/docs/source/arg_dev_docs.md b/docs/source/arg_dev_docs.md new file mode 100644 index 0000000..d96fd05 --- /dev/null +++ b/docs/source/arg_dev_docs.md @@ -0,0 +1,133 @@ +# Documentation Generation + +These instructions will walk you through generating the Argtable project's +documentation on your local system using the same documentation sources +as we use to create the online documentation found at +https://www.argtable.org + +## Documentation overview + +The Argtable project content is written using the MyST (Markedly Structured +Text) markup language (`.md` file extension) with Sphinx extensions, and +processed using Sphinx to create a formatted stand-alone website. Developers can +view this content either in its raw form as `.md` markup files, or you can +generate the HTML content and view it with a web browser directly on your +workstation. This same `.md` content is also fed into the Argtable project's +public website documentation area (maybe with a different theme applied). + +You can read details about [MyST](https://myst-parser.readthedocs.io), and +[Sphinx](https://www.sphinx-doc.org) from their respective websites. + +The project's documentation contains the following items: + +- MyST source files used to generate documentation found at the + https://www.argtable.org website. All of the MyST sources can be found in the + `/docs/source` directory. + +- Doxygen-generated material used to create all API-specific documents + also found at + +The MyST files are processed by the Sphinx documentation system, and make use of +the breathe extension for including the Doxygen-generated API material. +Additional tools are required to generate the documentation locally, as +described in the following sections. + +## Installing the documentation processors + +Our documentation processing has been tested to run with: + +- Doxygen version 1.10.0 +- Sphinx version 7.3.7 +- Breathe version 4.35.0 +- Furo Sphinx Theme version 2024.4.27 +- MyST Parser version 3.0.0 + +In order to install the documentation tools, first create a Python virtual +environment. Then install additional tools that are only required to generate +the documentation, as described below. + +### Doxygen + +On Ubuntu Linux: + +```shell +$ sudo apt install doxygen +``` + +On Fedora Linux: + +```shell +$ sudo dnf install doxygen +``` + +On Arch Linux: + +```shell +$ sudo pacman -S doxygen +``` + +On macOS: + +```shell +$ brew install doxygen +``` + +On Windows in an Administrator ``cmd.exe`` prompt: + +```shell +$ choco install doxygen.install +``` + +### Sphinx, Breathe, Furo, and MyST + +```shell +$ python --version +Python 3.11.5 + +$ python -m venv .py311 +$ .py311/Scripts/activate.bat + +(.py311) $ pip install --upgrade sphinx +(.py311) $ pip install --upgrade furo +(.py311) $ pip install --upgrade breathe +(.py311) $ pip install --upgrade myst-parser +``` + +## Documentation presentation theme + +Sphinx supports easy customization of the generated documentation appearance +through the use of themes. Replace the theme files and do another `make +html` and the output layout and style is changed. The `furo` theme +is installed as part of the step you took in the getting started guide. + +## Running the documentation processors + +The `/docs` directory in your cloned copy of the Argtable project git +repo has all the `.md` source files, extra tools, and Makefile for +generating a local copy of the Argtable project's technical documentation. +Assuming the local Argtable project copy is in a folder `argtable3` in your home +folder, here are the commands to generate the html content locally: + +```shell +(.py311) $ cd argtable3/docs +(.py311) $ doxygen +(.py311) $ make html +``` + +:::{warning} +The documentation build system creates copies in the build directory of every +`.md` file used to generate the documentation, along with dependencies +referenced by those `.md` files. + +This means that Sphinx warnings and errors refer to the **copies**, and **not +the version-controlled original files**. Be careful to make sure you don't +accidentally edit the copy of the file in an error message, as these changes +will not be saved. +::: + +Depending on your development system, it will take up to one minutes to collect +and generate the HTML content. When done, you can view the HTML output with +your browser started at `docs/build/html/index.html`. + +If you add or remove a files or want to build the documentation from scratch, +just run `make clean` and then `make html` again. diff --git a/docs/source/arg_dev_internals.md b/docs/source/arg_dev_internals.md new file mode 100644 index 0000000..949d7ab --- /dev/null +++ b/docs/source/arg_dev_internals.md @@ -0,0 +1 @@ +# Internals diff --git a/docs/source/arg_dev_tests.md b/docs/source/arg_dev_tests.md new file mode 100644 index 0000000..943fa8a --- /dev/null +++ b/docs/source/arg_dev_tests.md @@ -0,0 +1 @@ +# Test Automation diff --git a/docs/source/arg_getting_started.md b/docs/source/arg_getting_started.md new file mode 100644 index 0000000..dd8baaa --- /dev/null +++ b/docs/source/arg_getting_started.md @@ -0,0 +1,97 @@ +# Getting Started + +Argtable3 is a single-file ANSI-C library. All you have to do is adding +`argtable3.c` to your projects, and including `argtable3.h` in your source code. + +For example, if you want to create a utility named util.exe that has the +following command-line options: + +```shell +$ util.exe --help +Usage: util.exe [-v] [--help] [--version] [--level=] [-o myfile] []... +Demonstrate command-line parsing in argtable3. + + --help display this help and exit + --version display version information and exit + --level= foo value + -v, --verbose verbose output + -o myfile output file + input files +``` + +You can implement the command-line parsing logic with Argtable3 in the following +way: + +```c +#include "argtable3.h" + +#include +#include + +/* global arg_xxx structs */ +arg_lit_t *verb, *help, *version; +arg_int_t *level; +arg_file_t *o, *file; +arg_end_t *end; + +int main(int argc, char *argv[]) +{ + /* the global arg_xxx structs are initialised within the argtable */ + void *argtable[] = { + help = arg_litn(NULL, "help", 0, 1, "display this help and exit"), + version = arg_litn(NULL, "version", 0, 1, "display version info and exit"), + level = arg_intn(NULL, "level", "", 0, 1, "foo value"), + verb = arg_litn("v", "verbose", 0, 1, "verbose output"), + o = arg_filen("o", NULL, "myfile", 0, 1, "output file"), + file = arg_filen(NULL, NULL, "", 1, 100, "input files"), + end = arg_end(20), + }; + + int exitcode = 0; + char progname[] = "util.exe"; + + int nerrors = arg_parse(argc, argv, argtable); + + /* special case: '--help' takes precedence over error reporting */ + if (help->count > 0) { + printf("Usage: %s", progname); + arg_print_syntax(stdout, argtable, "\n"); + printf("Demonstrate command-line parsing in argtable3.\n\n"); + arg_print_glossary(stdout, argtable, " %-25s %s\n"); + exitcode = 0; + goto exit; + } + + /* If the parser returned any errors then display them and exit */ + if (nerrors > 0) { + /* Display the error details contained in the arg_end struct.*/ + arg_print_errors(stdout, end, progname); + printf("Try '%s --help' for more information.\n", progname); + exitcode = 1; + goto exit; + } + +exit: + /* deallocate each non-null entry in argtable[] */ + arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); + return exitcode; +} +``` + +To build the program with Microsoft Visual C++, you can open the Visual Studio +Developer Command Prompt window, and type the following command: + +```shell +C:\> cl.exe util.c argtable3.c +``` + +To build the program with GCC, MinGW, or Cygwin, you can open a shell window and +type the following command: + +```shell +$ gcc util.c argtable3.c +``` + +If you can successfully build the program and execute `util.exe --help` to see +the help message, it means you’ve learned how to integrate Argtable3 into your +program. diff --git a/docs/source/arg_installation.md b/docs/source/arg_installation.md new file mode 100644 index 0000000..1f454f3 --- /dev/null +++ b/docs/source/arg_installation.md @@ -0,0 +1,173 @@ +# Installation + +You can embed the amalgamation source files in your projects, add Argtable3 as a +dependency in the vcpkg manifest, install Argtable3 as a system-wide CMake +package, or build the library from release archives. + +## Embed Amalgamation Source Files + +:::{note} +We no longer provide the amalgamation source files (`argtable3.c` and +`argtable3.h`) in the repository. You can get the amalgamation distribution +either from the release page (`argtable--amalgamation.(zip|tar.gz)`), +or generate the distribution yourself by using the generator under the `tools` +directory: + +1. Navigate to the `tools` directory. +2. Run `./build dist`, which will generate the distribution under the `/dist` + directory. +::: + +Add `argtable3.c` and `argtable3.h` from the amalgamation distribution to your +projects. This is the simplest and recommended way to use Argtable3: it not only +removes the hassle of building the library, but also allows compilers to do +better inter-procedure optimization. + + +## Install for a Single Project with vcpkg Manifest + +[vcpkg](https://vcpkg.io) is an open source C/C++ package manager based on +CMake, and it supports certain stable releases of Argtable3. To add the library +to your CMake project, it's recommended to add vcpkg as a submodule to your +project repo and use it to manage project dependencies. All libraries installed +in this way can only be consumed by the project and won't impact other projects +in the system. + +If your project is under `D:/projects/demo` and the vcpkg submodule is under +`D:/projects/demo/deps/vcpkg`, first you need to add Argtable3 to the manifest, +`D:/projects/demo/vcpkg.json`: +``` +{ + "name": "demo", + "version": "0.0.1", + "dependencies": [ + { + "name": "argtable3", + "version>=": "3.2.1" + } + ], + "builtin-baseline": "92b42c4c680defe94f1665a847d04ded890f372e" +} +``` + +To add Argtable3 to your CMake scripts, you need to integrate the local vcpkg to +CMake by setting the `CMAKE_TOOLCHAIN_FILE` variable. You also need to link to +the static VC runtime (`/MT` or `/MTd`) if you want to use the static library +version of Argtable3: +``` +cmake_minimum_required(VERSION 3.18) + +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/deps/vcpkg/scripts/buildsystems/vcpkg.cmake + CACHE STRING "Vcpkg toolchain file") + +project(versionstest) + +add_executable(main main.cpp) + +find_package(Argtable3 CONFIG REQUIRED) +target_link_libraries(main PRIVATE argtable3::argtable3) + +if(VCPKG_TARGET_TRIPLET STREQUAL "x64-windows-static") + set_property(TARGET main PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() +``` + +Now you can run `cmake` to install Argtable3, configure and generate build +scripts, and build the project: +``` +$ mkdir build +$ cd build +$ cmake .. -DVCPKG_TARGET_TRIPLET=x64-windows-static +$ cmake --build . +``` + +## Install for All Projects with vcpkg + +If you want to make Argtable3 available for all projects in the system, you can +clone vcpkg to any directory and install packages there. Assuming vcpkg has been +cloned in `D:/dev/vcpkg` and the directory has been added to `PATH`, you can +install the static library version of Argtable3 in `D:/dev/vcpkg/installed`: +``` +$ vcpkg install argtable3:x64-windows-static +``` + +Since each developer may clone vcpkg in a different place, it may not be +appropriate to specify the `CMAKE_TOOLCHAIN_FILE` variable in `CMakeLists.txt`. +Therefore, you should remove setting the `CMAKE_TOOLCHAIN_FILE` variable in the +`CMakeLists.txt` example above, and set the variable in the command line: +``` +$ mkdir build +$ cd build +$ cmake .. -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE=D:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake +$ cmake --build . +``` + + +## Build from Release Archives or Source + +If none of the methods above suits your needs, or if you want to help developing +Argtable3, you can always build from archives on the release page or from the +repository. + +* If you use GCC (Linux, MacOSX, MinGW, Cygwin), run: + + ``` + $ mkdir build + $ cd build + $ cmake -DCMAKE_BUILD_TYPE=Debug .. + $ make + $ make test + ``` + + Makefile-based generators in CMake only support one configuration at a time, + so you need to specify `CMAKE_BUILD_TYPE` to `Debug`, `Release`, `MinSizeRel`, + or `RelWithDebInfo`. To build multiple configurations, you need to create a + build directory for each configuraiton. + + Since v3.2.1, CMake scripts will check `BUILD_SHARED_LIBS` and build either + the static library or the dynamic library at a time. `BUILD_SHARED_LIBS` is + `OFF` by default, so if you want to build the dynamic library, you have to set + `BUILD_SHARED_LIBS` to `ON` explicitly: + + ``` + $ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON .. + ``` + + To cleanup, run `make clean` or remove the build directory: + + ``` + $ rm -rf build + ``` + +* If you use Microsoft Visual C++ compiler, run: + + ``` + $ mkdir build + $ cd build + $ cmake -G "Visual Studio 15 2017 Win64" .. + $ cmake --build . --config Debug + $ ctest -C Debug + ``` + + You can also use Visual Studio 2017 IDE to open the generated solution. To + cleanup, just remove the `build` directory. + + +To build a tagged version, go to the project root directory, and use the +`Makefile` in the project root folder to check out the specified version: + + ``` + $ make taglist + Available TAGs: + v3.1.1.432a160 + $ make co TAG=v3.1.1.432a160 + $ cd .tags/v3.1.1.432a160 + $ mkdir build + $ cd build + $ cmake .. + $ make + $ make test + ``` + +You will find the shared library (or Windows DLL), static library, and the +amalgamation distribution under the build directory. diff --git a/docs/source/assets/doc-gen-flow.png b/docs/source/assets/doc-gen-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..837563a6fbfdd42bafd50b86813c8d2f19c8327f GIT binary patch literal 23858 zcmZU*2UL?w@IDL)Md<_urHDWP1p(0>6mqEJRKVSJ@U@mn<0@^$Y)ofwiM%| zRd4>Pi-^byS(zMeX#Q0CX>DXXsKa`%w70wnnO*uDF

7Z;29)h5rBkBbco;Xm7$@ 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 MYJK^&iAUo90nbrI6951J literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..5516488 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,43 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'Argtable' +copyright = '2024, Argtable Project members and individual contributors' +author = 'Tom G. Huang' +release = '3.1.5' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ['breathe', 'myst_parser'] + +templates_path = ['_templates'] +exclude_patterns = [] + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'furo' +html_static_path = ['_static'] +html_css_files = ['custom.css'] +html_theme_options = { + 'light_css_variables': { + 'font-stack': 'Open Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji', + }, +} + +# -- Options for Breathe extension ------------------------------------------- +breathe_projects = { "argtable": 'xml' } +breathe_default_project = "argtable" +breathe_order_parameters_first = True +breathe_domain_by_extension = {"h" : "c"} +breathe_default_members = ('members', 'undoc-members') +breathe_show_define_initializer = True + +# -- Options for MyST extension ------------------------------------------- +myst_enable_extensions = ['colon_fence'] \ No newline at end of file diff --git a/docs/source/index.md b/docs/source/index.md new file mode 100644 index 0000000..6483744 --- /dev/null +++ b/docs/source/index.md @@ -0,0 +1,195 @@ +% Copyright (c) 2024, Tom G. Huang +% https://xtensor.readthedocs.io/en/latest/index.html +% https://github.com/xtensor-stack/xtensor/tree/master/docs/source +% https://fmt.dev/latest/index.html +% https://github.com/fmtlib/fmt/tree/master/doc +% https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html# +% https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/ +% https://docs.zephyrproject.org/latest/ +% https://github.com/zephyrproject-rtos/zephyr/tree/master/doc +% https://gist.github.com/dupuy/1855764 + +# Introduction + +Argtable is an open source ANSI C library that parses GNU-style command-line +options. It simplifies command-line parsing by defining a declarative-style API +that you can use to specify what your command-line syntax looks like. Argtable +will automatically generate consistent error handling logic and textual +descriptions of the command line syntax, which are essential but tedious to +implement for a robust CLI program. For example, to create a CLI program that +looks like: + +```shell +$ util.exe --help +Usage: util.exe [-v] [--help] [--version] [--level=] [-o myfile] []... +Demonstrate command-line parsing in argtable3. + +--help display this help and exit +--version display version information and exit +--level= foo value +-v, --verbose verbose output +-o myfile output file + input files +``` + +:::{note} + +This documentation is for the latest Argtable **v3 series**, which is derived +from Argtable v2 series created by [Stewart +Heitmann](mailto:sheitmann@users.sourceforge.net). **Argtable3 is not +backward-compatible**. Therefore, if you want to use Argtable2 API, you have to +go to the [Argtable2 web site](http://argtable.sourceforge.net/) and get the +source code from its [Sourceforge.net project +page](http://sourceforge.net/projects/argtable/). +::: + +You can implement the command-line parsing logic with Argtable in the following code snippet: + +```c +#include "argtable3.h" + +/* global arg_xxx structs */ +struct arg_lit *verb, *help, *version; +struct arg_int *level; +struct arg_file *o, *file; +struct arg_end *end; + +int main(int argc, char *argv[]) +{ + /* the global arg_xxx structs are initialised within the argtable */ + void *argtable[] = { + help = arg_litn(NULL, "help", 0, 1, "display this help and exit"), + version = arg_litn(NULL, "version", 0, 1, "display version info and exit"), + level = arg_intn(NULL, "level", "", 0, 1, "foo value"), + verb = arg_litn("v", "verbose", 0, 1, "verbose output"), + o = arg_filen("o", NULL, "myfile", 0, 1, "output file"), + file = arg_filen(NULL, NULL, "", 1, 100, "input files"), + end = arg_end(20), + }; + + int exitcode = 0; + char progname[] = "util.exe"; + + int nerrors; + nerrors = arg_parse(argc,argv,argtable); + + /* special case: '--help' takes precedence over error reporting */ + if (help->count > 0) + { + printf("Usage: %s", progname); + arg_print_syntax(stdout, argtable, "\n"); + printf("Demonstrate command-line parsing in argtable3.\n\n"); + arg_print_glossary(stdout, argtable, " %-25s %s\n"); + exitcode = 0; + goto exit; + } + + /* If the parser returned any errors then display them and exit */ + if (nerrors > 0) + { + /* Display the error details contained in the arg_end struct.*/ + arg_print_errors(stdout, end, progname); + printf("Try '%s --help' for more information.\n", progname); + exitcode = 1; + goto exit; + } + +exit: + /* deallocate each non-null entry in argtable[] */ + arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); + return exitcode; +} +``` + + +## Features + +Here is a list of reasons why you should include Argtable in your C/C++ toolbox: + +- **GNU-style command-line syntax**: Use the standard and cross-platform way to express commands. +- **Declarative API**: Eliminate complex parsing logic by specifying what instead of elaborating how. +- **Built-in error handling**: Generate consistent error handling logic. +- **Built-in help messages**: Generate consistent command-line syntax descriptions. +- **Written in ANSI C**: Easy to create bindings for other languages. +- **Readable source code**: Well-commented source code with 100% branch test coverage. +- **Single-file library**: No tedious build scripts. Just drop a single source file into your projects. +- **Self-contained**: No external dependencies. +- **Cross-platform**: Available on most UNIX-like systems, Windows, and embedded systems. +- **BSD-licensed**: Use the library for any purpose, including in commercial programs. + + +## What’s Next + +If you want to learn how to use Argtable3, you can start from the tutorial. If +you want to learn from examples, you can check a list of sample programs in the +repository. And if you find any issue of the documentation or code, you can +submit an issue to the Github project page. + +CLI programs have become more and more important in the cloud computing era. We +hope that Argtable can contribute to the Renaissance of CLI and help to make +both developers’ and users’ life easier. + + +## Acknowledgements + +- *Stewart Heitmann* for creating the original argtable-1.x and argtable-2.x libraries. +- *Nina Clemson* for editing the original argtable-1.0 documentation. +- *Livio Bertacco* for contributing bug fixes and the argtable-2.x Visual C++ Makefiles. +- *Justin Dearing* for contributing bug fixes and Windows DLL support, plus code support for the Open Watcom compiler and help with the Mac OS X configuration. +- *Asa Packer* for contributing bug fixes and upgrades to the Visual C++ Makefiles. +- *Danilo Cicerone* for the Italian translation of “Introduction to Argtable-2x” and the argtable devpak. +- *Uli Fouquet* for configuration patches and documentation related to cross-compiling argtable from Unix to Windows as well as providing the arg_print_glossary_gnu function. +- *Shachar Schemesh* for integrating argtable into Debian Linux and kick-starting the migration to automake/autoconf. +- *Jasper Lievisse Adriaanse* for maintaining the argtable package in OpenBSD ports. +- *Ulrich Mohr* for bug fixes relating to Texas Instrument DSP platforms. +- *John Vickers* and *Steve O’Neil* for bug fixes relating to Solaris/Motorola platforms. +- *Lori A. Pritchett-Sheats* for fixing a makefile bug relating to “make dist”. +- *Paolo Bormida* for instructions on building argtable with date and regex support on Windows. +- *Michel Valin* for bug fixes relating to the configure scripts on IBM AIX platforms and instructions on compiling the example code under AIX. +- *Steve Christensen* for providing prebuilt packages for SPARC/Solaris and x86/Solaris platforms on www.sunfreeware.com. +- *Jess Portnoy* for reworking the rpm package and integrating argtable into Fedora Linux. +- *Michael Brown* for incorporating support for pkg-config into the autoconf scripts. +- *Alexander Lindert* for extensions to the parser to support hex, octal and binary integer formats as well as KB/MB/GB suffixes. +- *Rob Zaborowski* for providing build configuration files for the CMake tool. +- *Moczik Gabor* for bug fixes relating to the parsing of filepaths and filename extensions. +- *Hanspeter Niederstrasser* for including the argtable package in FinkProject for Mac OS X. + + +% Plan to add the following pages: +% - multi_commands +% - custom_format +% - regex +% - tcl +% - alias +% - configuration +:::{toctree} +:caption: USAGE +:maxdepth: 1 +:hidden: true + +arg_installation.md +arg_getting_started.md +::: + +:::{toctree} +:caption: API REFERENCE +:maxdepth: 1 +:hidden: true + +arg_api_parsing.md +arg_api_output.md +arg_api_dyna_string.md +arg_api_subcommand.md +arg_api_deprecated.md +::: + +:::{toctree} +:caption: DEVELOPER ZONE +:maxdepth: 1 +:hidden: true + +arg_dev_build.md +arg_dev_internals.md +arg_dev_tests.md +arg_dev_docs.md +:::