Skip to content

Commit

Permalink
Merge branch 'master' into fix/export_operator_symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
theodelrieu authored Dec 10, 2019
2 parents e6793d0 + a3e66b9 commit 0d4bac6
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 45 deletions.
77 changes: 52 additions & 25 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,32 @@ matrix:
include:
- os: linux
env:
- COMPILER=g++-5 STDLIB=libc++
- COMPILER=g++-7
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'george-edison55-precise-backports']
packages: ["g++-5", "cmake-data", "cmake"]
sources: ['ubuntu-toolchain-r-test']
packages: ["g++-7", "cmake-data", "cmake"]
- os: linux
env:
- COMPILER=g++-4.8 USE_BOOST_REGEX=ON
- COMPILER=g++-8
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'george-edison55-precise-backports', 'boost-latest']
packages: ["g++-4.8", "cmake-data", "cmake", "libboost-regex1.55-dev"]
sources: ['ubuntu-toolchain-r-test']
packages: ["g++-8", "cmake-data", "cmake"]
- os: linux
env:
- COMPILER=g++-9
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ["g++-9", "cmake-data", "cmake"]
- os: linux
env:
- COMPILER=g++-9 USE_BOOST_REGEX=ON
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ["g++-9", "cmake-data", "cmake", "libboost-regex-dev"]

- os: linux
env:
Expand All @@ -28,41 +42,54 @@ matrix:

- os: linux
env:
- COMPILER=clang++-3.7 STDLIB=libc++
- COMPILER=clang++-8 STDLIB=libc++
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7', 'george-edison55-precise-backports']
packages: ["clang-3.7", "cmake-data", "cmake"]
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-8']
packages: ["clang-8", "cmake-data", "cmake"]

- os: osx
osx_image: xcode6.4
osx_image: xcode9.4
env:
- COMPILER=clang++ V='Apple LLVM 6.4'
- COMPILER=clang++ V='Apple LLVM 6.4' WITH_CPP14=true
- COMPILER=clang++ V='Apple LLVM 9.1'
- COMPILER=clang++ V='Apple LLVM 9.1' WITH_CPP14=true

- os: osx
osx_image: xcode7
osx_image: xcode10.3
env:
- COMPILER=clang++ V='Apple LLVM 7.0'
- COMPILER=clang++ V='Apple LLVM 7.0' WITH_CPP14=true
- COMPILER=clang++ V='Apple LLVM 10.0'
- COMPILER=clang++ V='Apple LLVM 10.0' WITH_CPP14=true
- os: osx
osx_image: xcode11.2
env:
- COMPILER=clang++ V='Apple LLVM 11.0'
- COMPILER=clang++ V='Apple LLVM 11.0' WITH_CPP14=true
- os: osx
osx_image: xcode11.2
env:
- COMPILER=clang++ V='Apple LLVM 11.0'
- COMPILER=clang++ V='Apple LLVM 11.0' WITH_CPP17=true

before_install:
- CMAKE_CXX_FLAGS+=" -Wall"
- |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
brew rm --force cmake && brew install cmake
if [[ "${WITH_CPP14}" == "true" ]]; then
CMAKE_OPTIONS+=" -DCMAKE_CXX_STANDARD=14"
fi
- |
if [[ "${WITH_CPP17}" == "true" ]]; then
CMAKE_OPTIONS+=" -DCMAKE_CXX_STANDARD=17"
fi
- CMAKE_CXX_FLAGS+=" -Wall"

- if [[ "${WITH_CPP14}" == "true" ]]; then CMAKE_OPTIONS+=" -DCMAKE_CXX_STANDARD=14"; fi
- |
if [[ "${USE_BOOST_REGEX}" == "ON" ]]; then
CMAKE_OPTIONS+=" -DUSE_BOOST_REGEX=ON"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_DEBUG=/usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_RELEASE=/usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_DEBUG=/usr/lib/x86_64-linux-gnu/libboost_regex.so"
CMAKE_OPTIONS+=" -DBoost_REGEX_LIBRARY_RELEASE=/usr/lib/x86_64-linux-gnu/libboost_regex.so"
fi
- |
if [[ "${STDLIB}" == "libc++" ]]; then
CMAKE_CXX_FLAGS+=" -stdlib=libc++"
fi
- if [[ "${STDLIB}" == "libc++" ]]; then CMAKE_CXX_FLAGS+=" -stdlib=libc++"; fi

- ${COMPILER} --version

before_script:
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(docopt_HEADERS
#============================================================================
# Compile targets
#============================================================================

add_library(docopt ${docopt_SOURCES} ${docopt_HEADERS})

target_include_directories(docopt PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/docopt>)
Expand Down
74 changes: 54 additions & 20 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
``docopt.cpp``: A C++11 Port
============================

Contents
--------

.. contents::
:local:
:depth: 3

docopt creates *beautiful* command-line interfaces
--------------------------------------------------

Expand Down Expand Up @@ -58,13 +66,40 @@ and instead can write only the help message--*the way you want it*.
Beat that! The option parser is generated based on the docstring above
that is passed to ``docopt::docopt`` function. ``docopt`` parses the usage
pattern (``"Usage: ..."``) and option descriptions (lines starting
with dash "``-``") and ensures that the program invocation matches the
with a dash "``-``") and ensures that the program invocation matches the
usage pattern; it parses options, arguments and commands based on
that. The basic idea is that *a good help message has all necessary
information in it to make a parser*.

Getting and using
-----------------

To get *docopt.cpp*, the simplest is to use `Conda <https://github.com/conda-forge/docopt.cpp-feedstock>`_::

conda install -c conda-forge docopt.cpp

Alternatively manual installation is done using (unix)::

git clone
cmake .
make install

To link *docopt.cpp*, the simplest is to use CMake. The general structure of your
``CMakeLists.txt`` would be as follows::

cmake_minimum_required(VERSION 3.1)

project(example)

find_package(docopt COMPONENTS CXX REQUIRED)
include_directories(${DOCOPT_INCLUDE_DIRS})

add_executable(${PROJECT_NAME} ...)

target_link_libraries(${PROJECT_NAME} docopt)

C++11 port details
---------------------------------------------------
------------------

This is a port of the ``docopt.py`` module (https://github.com/docopt/docopt),
and we have tried to maintain full feature parity (and code structure) as the
Expand All @@ -80,7 +115,7 @@ to work with docopt:

GCC-4.8 can work, but the std::regex module needs to be replaced with ``Boost.Regex``.
In that case, you will need to define ``DOCTOPT_USE_BOOST_REGEX`` when compiling
docopt, and link your code with the appropriated Boost libraries. A relativley
docopt, and link your code with the appropriated Boost libraries. A relatively
recent version of Boost is needed: 1.55 works, but 1.46 does not for example.

This port is licensed under the MIT license, just like the original module.
Expand All @@ -101,7 +136,7 @@ The differences from the Python port are:
some of the regex's had to be restructured and additional loops used.

API
---------------------------------------------------
---

.. code:: c++

Expand Down Expand Up @@ -182,16 +217,15 @@ If any parsing error (in either the usage, or due to incorrect user inputs) is
encountered, the program will exit with exit code -1.

Note that there is another function that does not exit on error, and instead will
propogate an exception that you can catch and process as you like. See the docopt.h file
propagate an exception that you can catch and process as you like. See the docopt.h file
for information on the exceptions and usage:

.. code:: c++

docopt::docopt_parse(doc, argv, help /* =true */, version /* =true */, options_first /* =false)


Help message format
---------------------------------------------------
-------------------

Help message consists of 2 parts:

Expand All @@ -210,7 +244,7 @@ Help message consists of 2 parts:
Their format is described below; other text is ignored.

Usage pattern format
----------------------------------------------------------------------
--------------------

**Usage pattern** is a substring of ``doc`` that starts with
``usage:`` (case *insensitive*) and ends with a *visibly* empty line.
Expand Down Expand Up @@ -263,7 +297,7 @@ Use the following constructs to specify patterns:
- **|** (pipe) **mutually exclusive** elements. Group them using **(
)** if one of the mutually exclusive elements is required:
``my_program (--clockwise | --counter-clockwise) TIME``. Group
them using **[ ]** if none of the mutually-exclusive elements are
them using **[ ]** if none of the mutually exclusive elements are
required: ``my_program [--left | --right]``.
- **...** (ellipsis) **one or more** elements. To specify that
arbitrary number of repeating elements could be accepted, use
Expand Down Expand Up @@ -291,7 +325,7 @@ then number of occurrences of the option will be counted. I.e.
``args['-v']`` will be ``2`` if program was invoked as ``my_program
-vv``. Same works for commands.

If your usage patterns allows to match same-named option with argument
If your usage pattern allows to match same-named option with argument
or positional argument several times, the matched arguments will be
collected into a list::

Expand All @@ -301,9 +335,8 @@ I.e. invoked with ``my_program file1 file2 --path=./here
--path=./there`` the returned dict will contain ``args['<file>'] ==
['file1', 'file2']`` and ``args['--path'] == ['./here', './there']``.


Option descriptions format
----------------------------------------------------------------------
--------------------------

**Option descriptions** consist of a list of options that you put
below your usage patterns.
Expand All @@ -328,7 +361,7 @@ The rules are as follows:
argument after space (or equals "``=``" sign) as shown below. Follow
either <angular-brackets> or UPPER-CASE convention for options'
arguments. You can use comma if you want to separate options. In
the example below, both lines are valid, however you are recommended
the example below, both lines are valid. However you are recommended
to stick to a single style.::

-o FILE --output=FILE # without comma, with "=" sign
Expand All @@ -352,7 +385,7 @@ The rules are as follows:

- If the option is not repeatable, the value inside ``[default: ...]``
will be interpreted as string. If it *is* repeatable, it will be
splited into a list on whitespace::
split into a list on whitespace::

Usage: my_program [--repeatable=<arg> --repeatable=<arg>]
[--another-repeatable=<arg>]...
Expand All @@ -368,18 +401,18 @@ The rules are as follows:
--not-repeatable=<arg> [default: ./here ./there]

Examples
----------------------------------------------------------------------
--------

We have an extensive list of `examples
<https://github.com/docopt/docopt/tree/master/examples>`_ which cover
every aspect of functionality of **docopt**. Try them out, read the
source if in doubt.

There are also very intersting applications and ideas at that page.
There are also very interesting applications and ideas at that page.
Check out the sister project for more information!

Subparsers, multi-level help and *huge* applications (like git)
----------------------------------------------------------------------
---------------------------------------------------------------

If you want to split your usage-pattern into several, implement
multi-level help (with separate help-screen for each subcommand),
Expand All @@ -391,7 +424,8 @@ we implemented a subset of git command-line interface as an example:
<https://github.com/docopt/docopt/tree/master/examples/git>`_

Compiling the example / Running the tests
----------------------------------------------------------------------
-----------------------------------------

The original Python module includes some language-agnostic unit tests,
and these can be run with this port as well.

Expand Down Expand Up @@ -425,7 +459,7 @@ You can also compile the example shown at the start (included as example.cpp)::
shoot: false

Development
---------------------------------------------------
-----------

Comments and suggestions are *very* welcome! If you find issues, please
file them and help improve our code!
Expand All @@ -436,7 +470,7 @@ we might want to first negotiate these changes into the Python code first.
However, bring it up! Let's hear it!

Changelog
---------------------------------------------------
---------

**docopt** follows `semantic versioning <http://semver.org>`_. The
first release with stable API will be 1.0.0 (soon).
Expand Down

0 comments on commit 0d4bac6

Please sign in to comment.