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 0000000..837563a Binary files /dev/null and b/docs/source/assets/doc-gen-flow.png differ 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 +:::