From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/program_options/Jamfile | 11 + src/boost/libs/program_options/README.md | 37 ++ src/boost/libs/program_options/build/Jamfile.v2 | 16 + src/boost/libs/program_options/ci/build.sh | 19 + src/boost/libs/program_options/ci/codecov.sh | 43 ++ src/boost/libs/program_options/ci/coverity.sh | 42 ++ src/boost/libs/program_options/ci/cppcheck.sh | 38 ++ src/boost/libs/program_options/ci/mingw.bat | 50 ++ src/boost/libs/program_options/example/Jamfile.v2 | 21 + .../program_options/example/config_file_types.cpp | 242 +++++++ .../libs/program_options/example/custom_syntax.cpp | 63 ++ .../libs/program_options/example/env_options.cpp | 47 ++ src/boost/libs/program_options/example/first.cpp | 51 ++ .../program_options/example/multiple_sources.cfg | 5 + .../program_options/example/multiple_sources.cpp | 121 ++++ .../libs/program_options/example/option_groups.cpp | 97 +++ .../example/options_description.cpp | 86 +++ .../program_options/example/options_heirarchy.cpp | 690 ++++++++++++++++++++ src/boost/libs/program_options/example/real.cpp | 96 +++ src/boost/libs/program_options/example/regex.cpp | 101 +++ .../libs/program_options/example/response_file.cpp | 94 +++ .../libs/program_options/example/response_file.rsp | 3 + src/boost/libs/program_options/index.html | 14 + src/boost/libs/program_options/meta/libraries.json | 15 + src/boost/libs/program_options/src/cmdline.cpp | 713 +++++++++++++++++++++ src/boost/libs/program_options/src/config_file.cpp | 198 ++++++ src/boost/libs/program_options/src/convert.cpp | 161 +++++ .../program_options/src/options_description.cpp | 699 ++++++++++++++++++++ src/boost/libs/program_options/src/parsers.cpp | 258 ++++++++ .../program_options/src/positional_options.cpp | 53 ++ src/boost/libs/program_options/src/split.cpp | 62 ++ .../program_options/src/utf8_codecvt_facet.cpp | 21 + .../libs/program_options/src/value_semantic.cpp | 428 +++++++++++++ .../libs/program_options/src/variables_map.cpp | 248 +++++++ src/boost/libs/program_options/src/winmain.cpp | 102 +++ src/boost/libs/program_options/test/Jamfile.v2 | 44 ++ .../libs/program_options/test/cmdline_test.cpp | 656 +++++++++++++++++++ .../libs/program_options/test/config_test.cfg | 9 + .../libs/program_options/test/exception_test.cpp | 264 ++++++++ .../program_options/test/exception_txt_test.cpp | 693 ++++++++++++++++++++ src/boost/libs/program_options/test/minitest.hpp | 25 + .../libs/program_options/test/optional_test.cpp | 53 ++ .../test/options_description_test.cpp | 347 ++++++++++ .../libs/program_options/test/parsers_test.cpp | 388 +++++++++++ .../test/positional_options_test.cpp | 91 +++ .../test/program_options_size_test.py | 53 ++ src/boost/libs/program_options/test/quick.cpp | 49 ++ .../libs/program_options/test/required_test.cfg | 1 + .../libs/program_options/test/required_test.cpp | 125 ++++ src/boost/libs/program_options/test/split_test.cpp | 189 ++++++ .../libs/program_options/test/test_convert.cpp | 146 +++++ src/boost/libs/program_options/test/ucs2.txt | Bin 0 -> 2750 bytes .../libs/program_options/test/unicode_test.cpp | 164 +++++ .../program_options/test/unrecognized_test.cpp | 88 +++ src/boost/libs/program_options/test/utf8.txt | Bin 0 -> 2622 bytes .../program_options/test/variable_map_test.cpp | 290 +++++++++ src/boost/libs/program_options/test/winmain.cpp | 74 +++ src/boost/libs/program_options/test/winmain.py | 39 ++ 58 files changed, 8733 insertions(+) create mode 100644 src/boost/libs/program_options/Jamfile create mode 100644 src/boost/libs/program_options/README.md create mode 100644 src/boost/libs/program_options/build/Jamfile.v2 create mode 100755 src/boost/libs/program_options/ci/build.sh create mode 100755 src/boost/libs/program_options/ci/codecov.sh create mode 100755 src/boost/libs/program_options/ci/coverity.sh create mode 100755 src/boost/libs/program_options/ci/cppcheck.sh create mode 100755 src/boost/libs/program_options/ci/mingw.bat create mode 100644 src/boost/libs/program_options/example/Jamfile.v2 create mode 100644 src/boost/libs/program_options/example/config_file_types.cpp create mode 100644 src/boost/libs/program_options/example/custom_syntax.cpp create mode 100644 src/boost/libs/program_options/example/env_options.cpp create mode 100644 src/boost/libs/program_options/example/first.cpp create mode 100644 src/boost/libs/program_options/example/multiple_sources.cfg create mode 100644 src/boost/libs/program_options/example/multiple_sources.cpp create mode 100644 src/boost/libs/program_options/example/option_groups.cpp create mode 100644 src/boost/libs/program_options/example/options_description.cpp create mode 100644 src/boost/libs/program_options/example/options_heirarchy.cpp create mode 100644 src/boost/libs/program_options/example/real.cpp create mode 100644 src/boost/libs/program_options/example/regex.cpp create mode 100644 src/boost/libs/program_options/example/response_file.cpp create mode 100644 src/boost/libs/program_options/example/response_file.rsp create mode 100644 src/boost/libs/program_options/index.html create mode 100644 src/boost/libs/program_options/meta/libraries.json create mode 100644 src/boost/libs/program_options/src/cmdline.cpp create mode 100644 src/boost/libs/program_options/src/config_file.cpp create mode 100644 src/boost/libs/program_options/src/convert.cpp create mode 100644 src/boost/libs/program_options/src/options_description.cpp create mode 100644 src/boost/libs/program_options/src/parsers.cpp create mode 100644 src/boost/libs/program_options/src/positional_options.cpp create mode 100644 src/boost/libs/program_options/src/split.cpp create mode 100644 src/boost/libs/program_options/src/utf8_codecvt_facet.cpp create mode 100644 src/boost/libs/program_options/src/value_semantic.cpp create mode 100644 src/boost/libs/program_options/src/variables_map.cpp create mode 100644 src/boost/libs/program_options/src/winmain.cpp create mode 100644 src/boost/libs/program_options/test/Jamfile.v2 create mode 100644 src/boost/libs/program_options/test/cmdline_test.cpp create mode 100644 src/boost/libs/program_options/test/config_test.cfg create mode 100644 src/boost/libs/program_options/test/exception_test.cpp create mode 100644 src/boost/libs/program_options/test/exception_txt_test.cpp create mode 100644 src/boost/libs/program_options/test/minitest.hpp create mode 100644 src/boost/libs/program_options/test/optional_test.cpp create mode 100644 src/boost/libs/program_options/test/options_description_test.cpp create mode 100644 src/boost/libs/program_options/test/parsers_test.cpp create mode 100644 src/boost/libs/program_options/test/positional_options_test.cpp create mode 100644 src/boost/libs/program_options/test/program_options_size_test.py create mode 100644 src/boost/libs/program_options/test/quick.cpp create mode 100644 src/boost/libs/program_options/test/required_test.cfg create mode 100644 src/boost/libs/program_options/test/required_test.cpp create mode 100644 src/boost/libs/program_options/test/split_test.cpp create mode 100644 src/boost/libs/program_options/test/test_convert.cpp create mode 100644 src/boost/libs/program_options/test/ucs2.txt create mode 100644 src/boost/libs/program_options/test/unicode_test.cpp create mode 100644 src/boost/libs/program_options/test/unrecognized_test.cpp create mode 100644 src/boost/libs/program_options/test/utf8.txt create mode 100644 src/boost/libs/program_options/test/variable_map_test.cpp create mode 100644 src/boost/libs/program_options/test/winmain.cpp create mode 100644 src/boost/libs/program_options/test/winmain.py (limited to 'src/boost/libs/program_options') diff --git a/src/boost/libs/program_options/Jamfile b/src/boost/libs/program_options/Jamfile new file mode 100644 index 00000000..f0de2e0b --- /dev/null +++ b/src/boost/libs/program_options/Jamfile @@ -0,0 +1,11 @@ +# Boost.ProgramOptions Library Jamfile +# +# Copyright (c) 2018 James E. King III +# +# Use, modification, and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# please order by name to ease maintenance +build-project example ; +build-project test ; diff --git a/src/boost/libs/program_options/README.md b/src/boost/libs/program_options/README.md new file mode 100644 index 00000000..b2bd595e --- /dev/null +++ b/src/boost/libs/program_options/README.md @@ -0,0 +1,37 @@ +Program Options, part of the collection of [Boost C++ Libraries](http://github.com/boostorg), allows for definition and acquisition of (name, value) pairs from the user via conventional methods such as command line and config file. It is roughly analogous to getopt_long, but for use with C++. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Requires Linking + +### Build Status +(in progress...) + +|Branch | Travis | Appveyor | codecov.io | Deps | Docs | Tests | +|:-------------: | ------ | -------- | ---------- | ---- | ---- | ----- | +|[`master`](https://github.com/boostorg/program_options/tree/master) | [![Build Status](https://travis-ci.org/boostorg/program_options.svg?branch=master)](https://travis-ci.org/boostorg/program_options) | [![Build status](https://ci.appveyor.com/api/projects/status/e0quisadwh1v7ok5/branch/master?svg=true)](https://ci.appveyor.com/project/vprus/program-options/branch/master) | [![codecov](https://codecov.io/gh/boostorg/program_options/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/program_options/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/program_options.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/program_options.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/program_options.html) +|[`develop`](https://github.com/boostorg/program_options/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/program_options.svg?branch=develop)](https://travis-ci.org/boostorg/program_options) | [![Build status](https://ci.appveyor.com/api/projects/status/e0quisadwh1v7ok5/branch/develop?svg=true)](https://ci.appveyor.com/project/vprus/program-options/branch/develop) | [![codecov](https://codecov.io/gh/boostorg/program_options/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/program_options/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/program_options.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/program_options.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/program_options.html) + +### Directories + +| Name | Purpose | +| --------- | ------------------------------ | +| `build` | build script for link library | +| `ci` | continuous integration scripts | +| `doc` | documentation | +| `example` | use case examples | +| `include` | headers | +| `src` | source code for link library | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-program_options): Be sure to read the documentation first to see if it answers your question. +* [Report bugs](https://github.com/boostorg/program_options/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* [Submit Pull Requests](https://github.com/boostorg/program_options/pulls) against the **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). Be sure to include tests proving your changes work properly. +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[program_options]` tag at the beginning of the subject line. diff --git a/src/boost/libs/program_options/build/Jamfile.v2 b/src/boost/libs/program_options/build/Jamfile.v2 new file mode 100644 index 00000000..852054d0 --- /dev/null +++ b/src/boost/libs/program_options/build/Jamfile.v2 @@ -0,0 +1,16 @@ + +project boost/program_options + : source-location ../src + ; + +SOURCES = + cmdline config_file options_description parsers variables_map + value_semantic positional_options utf8_codecvt_facet + convert winmain split + ; + +boost-lib program_options + : $(SOURCES).cpp + : # See https://svn.boost.org/trac/boost/ticket/5049 + hpux,gcc:_INCLUDE_STDC__SOURCE_199901 + ; \ No newline at end of file diff --git a/src/boost/libs/program_options/ci/build.sh b/src/boost/libs/program_options/ci/build.sh new file mode 100755 index 00000000..49dd24ae --- /dev/null +++ b/src/boost/libs/program_options/ci/build.sh @@ -0,0 +1,19 @@ +#! /bin/bash +# +# Copyright 2017 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a bjam build +# cwd should be $BOOST_ROOT/libs/$SELF before running +# + +set -ex + +# default language level: c++03 +if [[ -z "$CXXSTD" ]]; then + CXXSTD=03 +fi + +$BOOST_ROOT/b2 . toolset=$TOOLSET cxxstd=$CXXSTD $CXXFLAGS $DEFINES $LINKFLAGS $TESTFLAGS $B2_ADDRESS_MODEL $B2_LINK $B2_THREADING $B2_VARIANT -j3 $* diff --git a/src/boost/libs/program_options/ci/codecov.sh b/src/boost/libs/program_options/ci/codecov.sh new file mode 100755 index 00000000..2f7ea10f --- /dev/null +++ b/src/boost/libs/program_options/ci/codecov.sh @@ -0,0 +1,43 @@ +#! /bin/bash +# +# Copyright 2017, 2018 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform codecov.io integration +# + +### +### NOTE: Make sure you grab .codecov.yml +### + +# assumes cwd is the top level directory of the boost project +# assumes an environment variable $SELF is the boost project name + +set -ex + +B2_VARIANT=debug +ci/build.sh cxxflags=-fprofile-arcs cxxflags=-ftest-coverage linkflags=-fprofile-arcs linkflags=-ftest-coverage + +# switch back to the original source code directory +cd $TRAVIS_BUILD_DIR + +# get the version of lcov +lcov --version + +# coverage files are in ../../b2 from this location +lcov --gcov-tool=gcov-7 --rc lcov_branch_coverage=1 --base-directory "$BOOST_ROOT/libs/$SELF" --directory "$BOOST_ROOT" --capture --output-file all.info + +# all.info contains all the coverage info for all projects - limit to ours +lcov --gcov-tool=gcov-7 --rc lcov_branch_coverage=1 --extract all.info "*/boost/$SELF/*" "*/libs/$SELF/src/*" --output-file coverage.info + +# dump a summary on the console - helps us identify problems in pathing +lcov --gcov-tool=gcov-7 --rc lcov_branch_coverage=1 --list coverage.info + +# +# upload to codecov.io +# +curl -s https://codecov.io/bash > .codecov +chmod +x .codecov +./.codecov -f coverage.info -X gcov -x "gcov-7" diff --git a/src/boost/libs/program_options/ci/coverity.sh b/src/boost/libs/program_options/ci/coverity.sh new file mode 100755 index 00000000..0de08a4c --- /dev/null +++ b/src/boost/libs/program_options/ci/coverity.sh @@ -0,0 +1,42 @@ +#! /bin/bash +# +# Copyright 2017 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a Coverity Scan build +# To skip the coverity integration download (which is huge) if +# you already have it from a previous run, add --skipdownload +# + +# +# Environment Variables +# +# COVERITY_SCAN_NOTIFICATION_EMAIL - email address to notify +# COVERITY_SCAN_TOKEN - the Coverity Scan token (should be secure) +# SELF - the boost libs directory name + +set -ex + +pushd /tmp +if [[ "$1" != "--skipdownload" ]]; then + rm -rf coverity_tool.tgz cov-analysis* + wget https://scan.coverity.com/download/linux64 --post-data "token=$COVERITY_SCAN_TOKEN&project=boostorg/$SELF" -O coverity_tool.tgz + tar xzf coverity_tool.tgz +fi +COVBIN=$(echo $(pwd)/cov-analysis*/bin) +export PATH=$COVBIN:$PATH +popd + +ci/build.sh clean +rm -rf cov-int/ +cov-build --dir cov-int ci/build.sh +tar cJf cov-int.tar.xz cov-int/ +curl --form token="$COVERITY_SCAN_TOKEN" \ + --form email="$COVERITY_SCAN_NOTIFICATION_EMAIL" \ + --form file=@cov-int.tar.xz \ + --form version="$(git describe --tags)" \ + --form description="boostorg/$SELF" \ + https://scan.coverity.com/builds?project="boostorg/$SELF" + diff --git a/src/boost/libs/program_options/ci/cppcheck.sh b/src/boost/libs/program_options/ci/cppcheck.sh new file mode 100755 index 00000000..7734ffcc --- /dev/null +++ b/src/boost/libs/program_options/ci/cppcheck.sh @@ -0,0 +1,38 @@ +#! /bin/bash +# +# Copyright 2018 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a cppcheck +# cwd should be $BOOST_ROOT before running +# + +set -ex + +# default language level: c++03 +if [[ -z "$CXXSTD" ]]; then + CXXSTD=03 +fi + +# Travis' ubuntu-trusty comes with cppcheck 1.62 which is pretty old +# default cppcheck version: 1.82 +if [[ -z "$CPPCHKVER" ]]; then + CPPCHKVER=1.82 +fi + +pushd ~ +wget https://github.com/danmar/cppcheck/archive/$CPPCHKVER.tar.gz +tar xzf $CPPCHKVER.tar.gz +mkdir cppcheck-build +cd cppcheck-build +cmake ../cppcheck-$CPPCHKVER -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=~/cppcheck +make -j3 install +popd + +~/cppcheck/bin/cppcheck -I. --std=c++$CXXSTD --enable=all --error-exitcode=1 \ + --force --check-config --suppress=*:boost/preprocessor/tuple/size.hpp \ + -UBOOST_USER_CONFIG -UBOOST_COMPILER_CONFIG -UBOOST_STDLIB_CONFIG -UBOOST_PLATFORM_CONFIG \ + libs/$SELF 2>&1 | grep -v 'Cppcheck does not need standard library headers' + diff --git a/src/boost/libs/program_options/ci/mingw.bat b/src/boost/libs/program_options/ci/mingw.bat new file mode 100755 index 00000000..bc189fdb --- /dev/null +++ b/src/boost/libs/program_options/ci/mingw.bat @@ -0,0 +1,50 @@ +:: +:: MinGW Build Script for Appveyor, leveraging the MSYS2 installation +:: Copyright (C) 2018 James E. King III +:: Distributed under the Boost Software License, Version 1.0. +:: (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) +:: + +@ECHO ON +SETLOCAL EnableDelayedExpansion + +:: Set up the toolset +echo using gcc : %FLAVOR% : %ARCH%-w64-mingw32-g++.exe ; > %USERPROFILE%\user-config.jam +SET UPPERFLAVOR=%FLAVOR% +CALL :TOUPPER UPPERFLAVOR + +:: Install packages needed to build boost +:: Optional: comment out ones this library does not need, +:: so people can copy this script to another library. + +FOR %%a IN ("gcc" "icu" "libiconv" "openssl" "xz" "zlib") DO ( + c:\msys64\usr\bin\env MSYSTEM=%UPPERFLAVOR% c:\msys64\usr\bin\bash -l -c ^ + "pacman --sync --needed --noconfirm %FLAVOR%/mingw-w64-%ARCH%-%%a" || EXIT /B +) +c:\msys64\usr\bin\env MSYSTEM=%UPPERFLAVOR% c:\msys64\usr\bin\bash -l -c ^ + "pacman --sync --needed --noconfirm python3" || EXIT /B + +:: +:: Now build things... +:: + +c:\msys64\usr\bin\env MSYSTEM=%UPPERFLAVOR% c:\msys64\usr\bin\bash -l -c ^ + "cd %CD:\=/% && ./bootstrap.sh --with-toolset=gcc" || EXIT /B + +c:\msys64\usr\bin\env MSYSTEM=%UPPERFLAVOR% c:\msys64\usr\bin\bash -l -c ^ + "cd %CD:\=/% && ./b2 libs/%SELF% toolset=gcc-%FLAVOR% cxxstd=%CXXSTD% %CXXFLAGS% %DEFINES% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3" || EXIT /B + +EXIT /B 0 + +:: +:: Function to uppercase a variable +:: from: https://stackoverflow.com/questions/34713621/batch-converting-variable-to-uppercase +:: + +:TOUPPER +@ECHO OFF +FOR %%a IN ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" + "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" + "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z" ) DO ( CALL SET %~1=%%%~1:%%~a%% ) +@ECHO ON +GOTO :EOF \ No newline at end of file diff --git a/src/boost/libs/program_options/example/Jamfile.v2 b/src/boost/libs/program_options/example/Jamfile.v2 new file mode 100644 index 00000000..9f0b1d8f --- /dev/null +++ b/src/boost/libs/program_options/example/Jamfile.v2 @@ -0,0 +1,21 @@ + +project + : requirements ../build//boost_program_options + true + static + ; + +exe first : first.cpp ; +exe options_description : options_description.cpp ; +exe multiple_sources : multiple_sources.cpp ; +exe custom_syntax : custom_syntax.cpp ; + +exe real : real.cpp ; +exe regex : regex.cpp /boost/regex//boost_regex ; + +# The following examples use C++ features beyond C++03. +# It would be possible to make compilation of each conditional on specific config check, +# for now just disable the compilation. +#exe config_file_types : config_file_types.cpp ; +#exe env_options : env_options.cpp ; +#exe options_heirarchy : options_heirarchy.cpp ; diff --git a/src/boost/libs/program_options/example/config_file_types.cpp b/src/boost/libs/program_options/example/config_file_types.cpp new file mode 100644 index 00000000..e466e94a --- /dev/null +++ b/src/boost/libs/program_options/example/config_file_types.cpp @@ -0,0 +1,242 @@ +// Copyright Thomas Kent 2016 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This example shows a config file (in ini format) being parsed by the +// program_options library. It includes a numebr of different value types. + +#include +namespace po = boost::program_options; + +#include +#include +#include +using namespace std; + +const double FLOAT_SEPERATION = 0.00000000001; +bool check_float(double test, double expected) +{ + double seperation = expected * (1 + FLOAT_SEPERATION) / expected; + if ((test < expected + seperation) && (test > expected - seperation)) + { + return true; + } + return false; +} + +stringstream make_file() +{ + stringstream ss; + ss << "# This file checks parsing of various types of config values\n"; + //FAILS: ss << "; a windows style comment\n"; + + ss << "global_string = global value\n"; + ss << "unregistered_entry = unregistered value\n"; + + ss << "\n[strings]\n"; + ss << "word = word\n"; + ss << "phrase = this is a phrase\n"; + ss << "quoted = \"quotes are in result\"\n"; + + ss << "\n[ints]\n"; + ss << "positive = 41\n"; + ss << "negative = -42\n"; + //FAILS: Lexical cast doesn't support hex, oct, or bin + //ss << "hex = 0x43\n"; + //ss << "oct = 044\n"; + //ss << "bin = 0b101010\n"; + + ss << "\n[floats]\n"; + ss << "positive = 51.1\n"; + ss << "negative = -52.1\n"; + ss << "double = 53.1234567890\n"; + ss << "int = 54\n"; + ss << "int_dot = 55.\n"; + ss << "dot = .56\n"; + ss << "exp_lower = 57.1e5\n"; + ss << "exp_upper = 58.1E5\n"; + ss << "exp_decimal = .591e5\n"; + ss << "exp_negative = 60.1e-5\n"; + ss << "exp_negative_val = -61.1e5\n"; + ss << "exp_negative_negative_val = -62.1e-5\n"; + + ss << "\n[booleans]\n"; + ss << "number_true = 1\n"; + ss << "number_false = 0\n"; + ss << "yn_true = yes\n"; + ss << "yn_false = no\n"; + ss << "tf_true = true\n"; + ss << "tf_false = false\n"; + ss << "onoff_true = on\n"; + ss << "onoff_false = off\n"; + ss << "present_equal_true = \n"; + //FAILS: Must be an = + //ss << "present_no_equal_true\n"; + + ss.seekp(ios_base::beg); + return ss; +} + +po::options_description set_options() +{ + po::options_description opts; + opts.add_options() + ("global_string", po::value()) + + ("strings.word", po::value()) + ("strings.phrase", po::value()) + ("strings.quoted", po::value()) + + ("ints.positive", po::value()) + ("ints.negative", po::value()) + ("ints.hex", po::value()) + ("ints.oct", po::value()) + ("ints.bin", po::value()) + + ("floats.positive", po::value()) + ("floats.negative", po::value()) + ("floats.double", po::value()) + ("floats.int", po::value()) + ("floats.int_dot", po::value()) + ("floats.dot", po::value()) + ("floats.exp_lower", po::value()) + ("floats.exp_upper", po::value()) + ("floats.exp_decimal", po::value()) + ("floats.exp_negative", po::value()) + ("floats.exp_negative_val", po::value()) + ("floats.exp_negative_negative_val", po::value()) + + // Load booleans as value, so they will require a --option=value on the command line + //("booleans.number_true", po::value()) + //("booleans.number_false", po::value()) + //("booleans.yn_true", po::value()) + //("booleans.yn_false", po::value()) + //("booleans.tf_true", po::value()) + //("booleans.tf_false", po::value()) + //("booleans.onoff_true", po::value()) + //("booleans.onoff_false", po::value()) + //("booleans.present_equal_true", po::value()) + //("booleans.present_no_equal_true", po::value()) + + // Load booleans as bool_switch, so that a --option will set it true on the command line + // The difference between these two types does not show up when parsing a file + ("booleans.number_true", po::bool_switch()) + ("booleans.number_false", po::bool_switch()) + ("booleans.yn_true", po::bool_switch()) + ("booleans.yn_false", po::bool_switch()) + ("booleans.tf_true", po::bool_switch()) + ("booleans.tf_false", po::bool_switch()) + ("booleans.onoff_true", po::bool_switch()) + ("booleans.onoff_false", po::bool_switch()) + ("booleans.present_equal_true", po::bool_switch()) + ("booleans.present_no_equal_true", po::bool_switch()) + ; + return opts; +} + +vector parse_file(stringstream &file, po::options_description &opts, po::variables_map &vm) +{ + const bool ALLOW_UNREGISTERED = true; + cout << file.str() << endl; + + po::parsed_options parsed = parse_config_file(file, opts, ALLOW_UNREGISTERED); + store(parsed, vm); + vector unregistered = po::collect_unrecognized(parsed.options, po::exclude_positional); + notify(vm); + + return unregistered; +} + +void check_results(po::variables_map &vm, vector unregistered) +{ + // Check that we got the correct values back + string expected_global_string = "global value"; + + string expected_unreg_option = "unregistered_entry"; + string expected_unreg_value = "unregistered value"; + + string expected_strings_word = "word"; + string expected_strings_phrase = "this is a phrase"; + string expected_strings_quoted = "\"quotes are in result\""; + + int expected_int_postitive = 41; + int expected_int_negative = -42; + int expected_int_hex = 0x43; + int expected_int_oct = 044; + int expected_int_bin = 0b101010; + + float expected_float_positive = 51.1f; + float expected_float_negative = -52.1f; + double expected_float_double = 53.1234567890; + float expected_float_int = 54.0f; + float expected_float_int_dot = 55.0f; + float expected_float_dot = .56f; + float expected_float_exp_lower = 57.1e5f; + float expected_float_exp_upper = 58.1E5f; + float expected_float_exp_decimal = .591e5f; + float expected_float_exp_negative = 60.1e-5f; + float expected_float_exp_negative_val = -61.1e5f; + float expected_float_exp_negative_negative_val = -62.1e-5f; + + bool expected_number_true = true; + bool expected_number_false = false; + bool expected_yn_true = true; + bool expected_yn_false = false; + bool expected_tf_true = true; + bool expected_tf_false = false; + bool expected_onoff_true = true; + bool expected_onoff_false = false; + bool expected_present_equal_true = true; + bool expected_present_no_equal_true = true; + + assert(vm["global_string"].as() == expected_global_string); + + assert(unregistered[0] == expected_unreg_option); + assert(unregistered[1] == expected_unreg_value); + + assert(vm["strings.word"].as() == expected_strings_word); + assert(vm["strings.phrase"].as() == expected_strings_phrase); + assert(vm["strings.quoted"].as() == expected_strings_quoted); + + assert(vm["ints.positive"].as() == expected_int_postitive); + assert(vm["ints.negative"].as() == expected_int_negative); + //assert(vm["ints.hex"].as() == expected_int_hex); + //assert(vm["ints.oct"].as() == expected_int_oct); + //assert(vm["ints.bin"].as() == expected_int_bin); + + assert(check_float(vm["floats.positive"].as(), expected_float_positive)); + assert(check_float(vm["floats.negative"].as(), expected_float_negative)); + assert(check_float(vm["floats.double"].as(), expected_float_double)); + assert(check_float(vm["floats.int"].as(), expected_float_int)); + assert(check_float(vm["floats.int_dot"].as(), expected_float_int_dot)); + assert(check_float(vm["floats.dot"].as(), expected_float_dot)); + assert(check_float(vm["floats.exp_lower"].as(), expected_float_exp_lower)); + assert(check_float(vm["floats.exp_upper"].as(), expected_float_exp_upper)); + assert(check_float(vm["floats.exp_decimal"].as(), expected_float_exp_decimal)); + assert(check_float(vm["floats.exp_negative"].as(), expected_float_exp_negative)); + assert(check_float(vm["floats.exp_negative_val"].as(), expected_float_exp_negative_val)); + assert(check_float(vm["floats.exp_negative_negative_val"].as(), expected_float_exp_negative_negative_val)); + + assert(vm["booleans.number_true"].as() == expected_number_true); + assert(vm["booleans.number_false"].as() == expected_number_false); + assert(vm["booleans.yn_true"].as() == expected_yn_true); + assert(vm["booleans.yn_false"].as() == expected_yn_false); + assert(vm["booleans.tf_true"].as() == expected_tf_true); + assert(vm["booleans.tf_false"].as() == expected_tf_false); + assert(vm["booleans.onoff_true"].as() == expected_onoff_true); + assert(vm["booleans.onoff_false"].as() == expected_onoff_false); + assert(vm["booleans.present_equal_true"].as() == expected_present_equal_true); + //assert(vm["booleans.present_no_equal_true"].as() == expected_present_no_equal_true); +} + +int main(int ac, char* av[]) +{ + auto file = make_file(); + auto opts = set_options(); + po::variables_map vars; + auto unregistered = parse_file(file, opts, vars); + check_results(vars, unregistered); + + return 0; +} diff --git a/src/boost/libs/program_options/example/custom_syntax.cpp b/src/boost/libs/program_options/example/custom_syntax.cpp new file mode 100644 index 00000000..829087d9 --- /dev/null +++ b/src/boost/libs/program_options/example/custom_syntax.cpp @@ -0,0 +1,63 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** This example shows how to support custom options syntax. + + It's possible to install 'custom_parser'. It will be invoked on all command + line tokens and can return name/value pair, or nothing. If it returns + nothing, usual processing will be done. +*/ + + +#include +#include +#include + +using namespace boost::program_options; + +#include +using namespace std; + +/* This custom option parse function recognize gcc-style + option "-fbar" / "-fno-bar". +*/ +pair reg_foo(const string& s) +{ + if (s.find("-f") == 0) { + if (s.substr(2, 3) == "no-") + return make_pair(s.substr(5), string("false")); + else + return make_pair(s.substr(2), string("true")); + } else { + return make_pair(string(), string()); + } +} + +int main(int ac, char* av[]) +{ + try { + options_description desc("Allowed options"); + desc.add_options() + ("help", "produce a help message") + ("foo", value(), "just an option") + ; + + variables_map vm; + store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo) + .run(), vm); + + if (vm.count("help")) { + cout << desc; + cout << "\nIn addition -ffoo and -fno-foo syntax are recognized.\n"; + } + if (vm.count("foo")) { + cout << "foo value with the value of " + << vm["foo"].as() << "\n"; + } + } + catch(exception& e) { + cout << e.what() << "\n"; + } +} diff --git a/src/boost/libs/program_options/example/env_options.cpp b/src/boost/libs/program_options/example/env_options.cpp new file mode 100644 index 00000000..bab37e25 --- /dev/null +++ b/src/boost/libs/program_options/example/env_options.cpp @@ -0,0 +1,47 @@ +// Copyright Thomas Kent 2016 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +namespace po = boost::program_options; +#include +#include + +std::string mapper(std::string env_var) +{ + // ensure the env_var is all caps + std::transform(env_var.begin(), env_var.end(), env_var.begin(), ::toupper); + + if (env_var == "PATH") return "path"; + if (env_var == "EXAMPLE_VERBOSE") return "verbosity"; + return ""; +} + +void get_env_options() +{ + po::options_description config("Configuration"); + config.add_options() + ("path", "the execution path") + ("verbosity", po::value()->default_value("INFO"), "set verbosity: DEBUG, INFO, WARN, ERROR, FATAL") + ; + + po::variables_map vm; + store(po::parse_environment(config, boost::function1(mapper)), vm); + notify(vm); + + if (vm.count("path")) + { + std::cout << "First 75 chars of the system path: \n"; + std::cout << vm["path"].as().substr(0, 75) << std::endl; + } + + std::cout << "Verbosity: " << vm["verbosity"].as() << std::endl; +} + +int main(int ac, char* av[]) +{ + get_env_options(); + + return 0; +} diff --git a/src/boost/libs/program_options/example/first.cpp b/src/boost/libs/program_options/example/first.cpp new file mode 100644 index 00000000..8763fec9 --- /dev/null +++ b/src/boost/libs/program_options/example/first.cpp @@ -0,0 +1,51 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* The simplest usage of the library. + */ + +#include +namespace po = boost::program_options; + +#include +#include +using namespace std; + +int main(int ac, char* av[]) +{ + try { + + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "produce help message") + ("compression", po::value(), "set compression level") + ; + + po::variables_map vm; + po::store(po::parse_command_line(ac, av, desc), vm); + po::notify(vm); + + if (vm.count("help")) { + cout << desc << "\n"; + return 0; + } + + if (vm.count("compression")) { + cout << "Compression level was set to " + << vm["compression"].as() << ".\n"; + } else { + cout << "Compression level was not set.\n"; + } + } + catch(exception& e) { + cerr << "error: " << e.what() << "\n"; + return 1; + } + catch(...) { + cerr << "Exception of unknown type!\n"; + } + + return 0; +} diff --git a/src/boost/libs/program_options/example/multiple_sources.cfg b/src/boost/libs/program_options/example/multiple_sources.cfg new file mode 100644 index 00000000..6966d004 --- /dev/null +++ b/src/boost/libs/program_options/example/multiple_sources.cfg @@ -0,0 +1,5 @@ +# +# Comment out this line to use hard-coded default value of 10 +# +optimization = 1 +include-path = /opt \ No newline at end of file diff --git a/src/boost/libs/program_options/example/multiple_sources.cpp b/src/boost/libs/program_options/example/multiple_sources.cpp new file mode 100644 index 00000000..22c8235b --- /dev/null +++ b/src/boost/libs/program_options/example/multiple_sources.cpp @@ -0,0 +1,121 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* Shows how to use both command line and config file. */ + +#include +namespace po = boost::program_options; + + +#include +#include +#include +using namespace std; + +// A helper function to simplify the main part. +template +ostream& operator<<(ostream& os, const vector& v) +{ + copy(v.begin(), v.end(), ostream_iterator(os, " ")); + return os; +} + + +int main(int ac, char* av[]) +{ + try { + int opt; + string config_file; + + // Declare a group of options that will be + // allowed only on command line + po::options_description generic("Generic options"); + generic.add_options() + ("version,v", "print version string") + ("help", "produce help message") + ("config,c", po::value(&config_file)->default_value("multiple_sources.cfg"), + "name of a file of a configuration.") + ; + + // Declare a group of options that will be + // allowed both on command line and in + // config file + po::options_description config("Configuration"); + config.add_options() + ("optimization", po::value(&opt)->default_value(10), + "optimization level") + ("include-path,I", + po::value< vector >()->composing(), + "include path") + ; + + // Hidden options, will be allowed both on command line and + // in config file, but will not be shown to the user. + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value< vector >(), "input file") + ; + + + po::options_description cmdline_options; + cmdline_options.add(generic).add(config).add(hidden); + + po::options_description config_file_options; + config_file_options.add(config).add(hidden); + + po::options_description visible("Allowed options"); + visible.add(generic).add(config); + + po::positional_options_description p; + p.add("input-file", -1); + + po::variables_map vm; + store(po::command_line_parser(ac, av). + options(cmdline_options).positional(p).run(), vm); + notify(vm); + + ifstream ifs(config_file.c_str()); + if (!ifs) + { + cout << "can not open config file: " << config_file << "\n"; + return 0; + } + else + { + store(parse_config_file(ifs, config_file_options), vm); + notify(vm); + } + + if (vm.count("help")) { + cout << visible << "\n"; + return 0; + } + + if (vm.count("version")) { + cout << "Multiple sources example, version 1.0\n"; + return 0; + } + + if (vm.count("include-path")) + { + cout << "Include paths are: " + << vm["include-path"].as< vector >() << "\n"; + } + + if (vm.count("input-file")) + { + cout << "Input files are: " + << vm["input-file"].as< vector >() << "\n"; + } + + cout << "Optimization level is " << opt << "\n"; + } + catch(exception& e) + { + cout << e.what() << "\n"; + return 1; + } + return 0; +} diff --git a/src/boost/libs/program_options/example/option_groups.cpp b/src/boost/libs/program_options/example/option_groups.cpp new file mode 100644 index 00000000..63e1fca4 --- /dev/null +++ b/src/boost/libs/program_options/example/option_groups.cpp @@ -0,0 +1,97 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** This example shows how to handle options groups. + + For a test, run: + + option_groups --help + option_groups --num-threads 10 + option_groups --help-module backend + + The first invocation would show to option groups, and will not show the + '--num-threads' options. The second invocation will still get the value of + the hidden '--num-threads' option. Finally, the third invocation will show + the options for the 'backend' module, including the '--num-threads' option. + +*/ + + +#include +#include +#include +#include +#include +using namespace boost; +using namespace boost::program_options; + +#include +#include +#include +using namespace std; + +int main(int ac, char* av[]) +{ + try { + // Declare three groups of options. + options_description general("General options"); + general.add_options() + ("help", "produce a help message") + ("help-module", value(), + "produce a help for a given module") + ("version", "output the version number") + ; + + options_description gui("GUI options"); + gui.add_options() + ("display", value(), "display to use") + ; + + options_description backend("Backend options"); + backend.add_options() + ("num-threads", value(), "the initial number of threads") + ; + + // Declare an options description instance which will include + // all the options + options_description all("Allowed options"); + all.add(general).add(gui).add(backend); + + // Declare an options description instance which will be shown + // to the user + options_description visible("Allowed options"); + visible.add(general).add(gui); + + + variables_map vm; + store(parse_command_line(ac, av, all), vm); + + if (vm.count("help")) + { + cout << visible; + return 0; + } + if (vm.count("help-module")) { + const string& s = vm["help-module"].as(); + if (s == "gui") { + cout << gui; + } else if (s == "backend") { + cout << backend; + } else { + cout << "Unknown module '" + << s << "' in the --help-module option\n"; + return 1; + } + return 0; + } + if (vm.count("num-threads")) { + cout << "The 'num-threads' options was set to " + << vm["num-threads"].as() << "\n"; + } + } + catch(std::exception& e) { + cout << e.what() << "\n"; + } +} diff --git a/src/boost/libs/program_options/example/options_description.cpp b/src/boost/libs/program_options/example/options_description.cpp new file mode 100644 index 00000000..e9ad2a67 --- /dev/null +++ b/src/boost/libs/program_options/example/options_description.cpp @@ -0,0 +1,86 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +using namespace boost; +namespace po = boost::program_options; + +#include +#include +#include +using namespace std; + + +// A helper function to simplify the main part. +template +ostream& operator<<(ostream& os, const vector& v) +{ + copy(v.begin(), v.end(), ostream_iterator(os, " ")); + return os; +} + +int main(int ac, char* av[]) +{ + try { + int opt; + int portnum; + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "produce help message") + ("optimization", po::value(&opt)->default_value(10), + "optimization level") + ("verbose,v", po::value()->implicit_value(1), + "enable verbosity (optionally specify level)") + ("listen,l", po::value(&portnum)->implicit_value(1001) + ->default_value(0,"no"), + "listen on a port.") + ("include-path,I", po::value< vector >(), + "include path") + ("input-file", po::value< vector >(), "input file") + ; + + po::positional_options_description p; + p.add("input-file", -1); + + po::variables_map vm; + po::store(po::command_line_parser(ac, av). + options(desc).positional(p).run(), vm); + po::notify(vm); + + if (vm.count("help")) { + cout << "Usage: options_description [options]\n"; + cout << desc; + return 0; + } + + if (vm.count("include-path")) + { + cout << "Include paths are: " + << vm["include-path"].as< vector >() << "\n"; + } + + if (vm.count("input-file")) + { + cout << "Input files are: " + << vm["input-file"].as< vector >() << "\n"; + } + + if (vm.count("verbose")) { + cout << "Verbosity enabled. Level is " << vm["verbose"].as() + << "\n"; + } + + cout << "Optimization level is " << opt << "\n"; + + cout << "Listen port is " << portnum << "\n"; + } + catch(std::exception& e) + { + cout << e.what() << "\n"; + return 1; + } + return 0; +} diff --git a/src/boost/libs/program_options/example/options_heirarchy.cpp b/src/boost/libs/program_options/example/options_heirarchy.cpp new file mode 100644 index 00000000..c913b149 --- /dev/null +++ b/src/boost/libs/program_options/example/options_heirarchy.cpp @@ -0,0 +1,690 @@ +// Copyright Thomas Kent 2016 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// This is an example of a program that uses multiple facets of the boost +// program_options library. It will go through different types of config +// options in a heirarchal manner: +// 1. Default options are set. +// 2. Command line options are set (they override defaults). +// 3. Environment options are set (they override defaults but not command +// line options). +// 4. Config files specified on the command line are read, if present, in +// the order specified. (these override defaults but not options from the +// other steps). +// 5. Default config file (default.cfg) is read, if present (it overrides +// defaults but not options from the other steps). +// +// See the bottom of this file for full usage examples +// + +#include +namespace po = boost::program_options; +#include +#include +#include +#include +#include + +const std::string version("1.0"); + +// Used to exit the program if the help/version option is set +class OptionsExitsProgram : public std::exception +{}; + +struct GuiOpts +{ + unsigned int width; + unsigned int height; +}; + +struct NetworkOpts +{ + std::string address; + unsigned short port; +}; + +class OptionsHeirarchy +{ +public: + // The constructor sets up all the various options that will be parsed + OptionsHeirarchy() + { + SetOptions(); + } + + // Parse options runs through the heirarchy doing all the parsing + void ParseOptions(int argc, char* argv[]) + { + ParseCommandLine(argc, argv); + CheckForHelp(); + CheckForVersion(); + ParseEnvironment(); + ParseConfigFiles(); + ParseDefaultConfigFile(); + } + + // Below is the interface to access the data, once ParseOptions has been run + std::string Path() + { + return results["path"].as(); + } + std::string Verbosity() + { + return results["verbosity"].as(); + } + std::vector IncludePath() + { + if (results.count("include-path")) + { + return results["include-path"].as>(); + } + return std::vector(); + } + std::string MasterFile() + { + if (results.count("master-file")) + { + return results["master-file"].as(); + } + return ""; + } + std::vector Files() + { + if (results.count("file")) + { + return results["file"].as>(); + } + return std::vector(); + } + bool GUI() + { + if (results["run-gui"].as()) + { + return true; + } + return false; + } + GuiOpts GuiValues() + { + GuiOpts opts; + opts.width = results["gui.width"].as(); + opts.height = results["gui.height"].as(); + return opts; + } + NetworkOpts NetworkValues() + { + NetworkOpts opts; + opts.address = results["network.ip"].as(); + opts.port = results["network.port"].as(); + return opts; + } + +private: + void SetOptions() + { + SetCommandLineOptions(); + SetCommonOptions(); + SetConfigOnlyOptions(); + SetEnvMapping(); + } + void SetCommandLineOptions() + { + command_line_options.add_options() + ("help,h", "display this help message") + ("version,v", "show program version") + ("config,c", po::value>(), + "config files to parse (always parses default.cfg)") + ; + hidden_command_line_options.add_options() + ("master-file", po::value()) + ("file", po::value>()) + ; + positional_options.add("master-file", 1); + positional_options.add("file", -1); + } + void SetCommonOptions() + { + common_options.add_options() + ("path", po::value()->default_value(""), + "the execution path to use (imports from environment if not specified)") + ("verbosity", po::value()->default_value("INFO"), + "set verbosity: DEBUG, INFO, WARN, ERROR, FATAL") + ("include-path,I", po::value>()->composing(), + "paths to search for include files") + ("run-gui", po::bool_switch(), "start the GUI") + ; + } + void SetConfigOnlyOptions() + { + config_only_options.add_options() + ("log-dir", po::value()->default_value("log")) + ("gui.height", po::value()->default_value(100)) + ("gui.width", po::value()->default_value(100)) + ("network.ip", po::value()->default_value("127.0.0.1")) + ("network.port", po::value()->default_value(12345)) + ; + // Run a parser here (with no command line options) to add these defaults into + // results, this way they will be enabled even if no config files are parsed. + store(po::command_line_parser(0, 0).options(config_only_options).run(), results); + notify(results); + } + void SetEnvMapping() + { + env_to_option["PATH"] = "path"; + env_to_option["EXAMPLE_VERBOSE"] = "verbosity"; + } + + + void ParseCommandLine(int argc, char* argv[]) + { + po::options_description cmd_opts; + cmd_opts.add(command_line_options).add(hidden_command_line_options).add(common_options); + store(po::command_line_parser(argc, argv). + options(cmd_opts).positional(positional_options).run(), results); + notify(results); + } + void CheckForHelp() + { + if (results.count("help")) + { + PrintHelp(); + } + } + void PrintHelp() + { + std::cout << "Program Options Example" << std::endl; + std::cout << "Usage: example [OPTION]... MASTER-FILE [FILE]...\n"; + std::cout << " or example [OPTION] --run-gui\n"; + po::options_description help_opts; + help_opts.add(command_line_options).add(common_options); + std::cout << help_opts << std::endl; + throw OptionsExitsProgram(); + } + void CheckForVersion() + { + if (results.count("version")) + { + PrintVersion(); + } + } + void PrintVersion() + { + std::cout << "Program Options Example " << version << std::endl; + throw OptionsExitsProgram(); + } + void ParseEnvironment() + { + store(po::parse_environment(common_options, + // The next two lines are the crazy syntax to use EnvironmentMapper as + // the lookup function for env->config name conversions + boost::function1( + std::bind1st(std::mem_fun(&OptionsHeirarchy::EnvironmentMapper), this))), + results); + notify(results); + } + std::string EnvironmentMapper(std::string env_var) + { + // ensure the env_var is all caps + std::transform(env_var.begin(), env_var.end(), env_var.begin(), ::toupper); + + auto entry = env_to_option.find(env_var); + if (entry != env_to_option.end()) + { + return entry->second; + } + return ""; + } + void ParseConfigFiles() + { + if (results.count("config")) + { + auto files = results["config"].as>(); + for (auto file = files.begin(); file != files.end(); file++) + { + LoadAConfigFile(*file); + } + } + } + void LoadAConfigFile(std::string filename) + { + bool ALLOW_UNREGISTERED = true; + + po::options_description config_opts; + config_opts.add(config_only_options).add(common_options); + + std::ifstream cfg_file(filename.c_str()); + if (cfg_file) + { + store(parse_config_file(cfg_file, config_opts, ALLOW_UNREGISTERED), results); + notify(results); + } + } + void ParseDefaultConfigFile() + { + LoadAConfigFile("default.cfg"); + } + + std::map env_to_option; + po::options_description config_only_options; + po::options_description common_options; + po::options_description command_line_options; + po::options_description hidden_command_line_options; + po::positional_options_description positional_options; + po::variables_map results; +}; + + +void get_env_options() +{ +} + +void PrintOptions(OptionsHeirarchy options) +{ + auto path = options.Path(); + if (path.length()) + { + std::cout << "First 75 chars of the system path: \n"; + std::cout << options.Path().substr(0, 75) << std::endl; + } + + std::cout << "Verbosity: " << options.Verbosity() << std::endl; + std::cout << "Include Path:\n"; + auto includePaths = options.IncludePath(); + for (auto path = includePaths.begin(); path != includePaths.end(); path++) + { + std::cout << " " << *path << std::endl; + } + std::cout << "Master-File: " << options.MasterFile() << std::endl; + std::cout << "Additional Files:\n"; + auto files = options.Files(); + for (auto file = files.begin(); file != files.end(); file++) + { + std::cout << " " << *file << std::endl; + } + + std::cout << "GUI Enabled: " << std::boolalpha << options.GUI() << std::endl; + if (options.GUI()) + { + auto gui_values = options.GuiValues(); + std::cout << "GUI Height: " << gui_values.height << std::endl; + std::cout << "GUI Width: " << gui_values.width << std::endl; + } + + auto network_values = options.NetworkValues(); + std::cout << "Network Address: " << network_values.address << std::endl; + std::cout << "Network Port: " << network_values.port << std::endl; +} + +int main(int ac, char* av[]) +{ + OptionsHeirarchy options; + try + { + options.ParseOptions(ac, av); + PrintOptions(options); + } + catch (OptionsExitsProgram){} + + return 0; +} + +/* +Full Usage Examples +=================== + +These were run on windows, so some results may show that environment, but +results should be similar on POSIX platforms. + +Help +---- +To see the help screen, with the available options just pass the --help (or -h) +parameter. The program will then exit. + + > example.exe --help + Program Options Example + Usage: example [OPTION]... MASTER-FILE [FILE]... + or example [OPTION] --run-gui + + -h [ --help ] display this help message + -v [ --version ] show program version + -c [ --config ] arg config files to parse (always parses default.cfg) + + --path arg the execution path to use (imports from + environment if not specified) + --verbosity arg (=INFO) set verbosity: DEBUG, INFO, WARN, ERROR, FATAL + -I [ --include-path ] arg paths to search for include files + --run-gui start the GUI + +Version is similar to help (--version or -v). + + > example.exe -v + Program Options Example 1.0 + +Basics +------ +Running without any options will get the default values (path is set from the +environment): + + > example.exe + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +We can easily override that environment path with a simple option: + + > example.exe --path a/b/c;d/e/f + First 75 chars of the system path: + a/b/c;d/e/f + Verbosity: INFO + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +You can use a space or equals sign after long options, also backslashes are +treated literally on windows, on POSIX they need to be escaped. + + > example.exe --path=a\b\c\;d\e\\f + First 75 chars of the system path: + a\b\c\;d\e\\f + Verbosity: INFO + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +For short options you can use a space: + + > example.exe -I path/to/includes + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + path\to\includes + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +Or you can put the option immediately after it: + + > example.exe -Ipath/to/includes + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + path\to\includes + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +The include path (--include-path or -I) option allows for multiple paths to be +specified (both on the command line and in config files) and combined into a +vector for use by the program. + + > example.exe --include-path=a/b/c --include-path d/e/f -I g/h/i -Ij/k/l + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + a/b/c + d/e/f + g/h/i + j/k/l + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +There are also the option of flags that do not take parameters and just set a +boolean value to true. In this case, running the gui also causes default values +for the gui to be output to the screen. + + > example.exe --run-gui + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + Master-File: + Additional Files: + GUI Enabled: true + GUI Height: 100 + GUI Width: 100 + Network Address: 127.0.0.1 + Network Port: 12345 + +There are also "positional" options at the end of the command line. The first +one specifies the "master" file the others are additional files. + + > example.exe --path=a-path -I an-include master.cpp additional1.cpp additional2.cpp + First 75 chars of the system path: + a-path + Verbosity: INFO + Include Path: + an-include + Master-File: master.cpp + Additional Files: + additional1.cpp + additional2.cpp + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +Environment Variables +--------------------- +In addition to the PATH environment variable, it also knows how to read the +EXAMPLE_VERBOSE environmental variable and use that to set the verbosity +option/ + + > set EXAMPLE_VERBOSE=DEBUG + > example.exe + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: DEBUG + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +However, if the --verboseity flag is also set, it will override the env +variable. This illustrates an important example, the way program_options works, +is that a parser will not override a value that has previously been set by +another parser. Thus the env parser doesn't override the command line parser. +(We will see this again in config files.) Default values are seperate from this +heirarcy, they only apply if no parser has set the value and it is being read. + + > set EXAMPLE_VERBOSE=DEBUG + > example.exe --verbosity=WARN + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: WARN + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +(You can unset an environmental variable with an empty set command) + + > set EXAMPLE_VERBOSE= + > example.exe + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + + +Config Files +------------ +Config files generally follow the [INI file format] +(https://en.wikipedia.org/wiki/INI_file) with a few exceptions. + +Values can be simply added tp options with an equal sign. Here are two include +paths added via the default config file (default.cfg), you can have optional +spaces around the equal sign. + + # You can use comments in a config file + include-path=first/default/path + include-path = second/default/path + +Results in + + > example.exe + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + first/default/path + second/default/path + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 127.0.0.1 + Network Port: 12345 + +Values can also be in sections of the config file. Again, editing default.cfg + + include-path=first/default/path + include-path = second/default/path + + [network] + ip=1.2.3.4 + port=3000 + +Results in + + > example.exe + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: INFO + Include Path: + first/default/path + second/default/path + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 1.2.3.4 + Network Port: 3000 + +This example is also setup to allow multiple config files to be specified on +the command line, which are checked before the default.cfg file is read (but +after the environment and command line parsing). Thus we can set the first.cfg +file to contain the following: + + verbosity=ERROR + + [network] + ip = 5.6.7.8 + +Results in: + + > example.exe --config first.cfg + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: ERROR + Include Path: + first/default/path + second/default/path + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 5.6.7.8 + Network Port: 3000 + +But since the config files are read after the command line, setting the +verbosity there causes the value in the file to be ignored. + + > example.exe --config first.cfg --verbosity=WARN + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: WARN + Include Path: + first/default/path + second/default/path + Master-File: + Additional Files: + GUI Enabled: false + Network Address: 5.6.7.8 + Network Port: 3000 + +The config files are parsed in the order they are received on the command line. +So adding the second.cfg file: + + verbosity=FATAL + run-gui=true + + [gui] + height=720 + width=1280 + +Results in a combination of all three config files: + + > example.exe --config first.cfg --config second.cfg + First 75 chars of the system path: + C:\Program Files (x86)\MSBuild\14.0\bin;C:\Perl\site\bin;C:\Perl\bin;C:\Pro + Verbosity: ERROR + Include Path: + first/default/path + second/default/path + Master-File: + Additional Files: + GUI Enabled: true + GUI Height: 720 + GUI Width: 1280 + Network Address: 5.6.7.8 + Network Port: 3000 + +Incidently the boolean run-gui option could have been set a number of ways +that all result in the C++ boolean value of true: + + run-gui=true + run-gui=on + run-gui=1 + run-gui=yes + run-gui= + +Since run-gui is an option that was set with the bool_switch type, which +forces its use on the command line without a parameter (i.e. --run-gui instead +of --run-gui=true) it can't be given a "false" option, bool_switch values can +only be turned true. If instead we had a value ("my-switch", po::value()) +that could be set at the command line --my-switch=true or --my-switch=false, or +any of the other types of boolean keywords true: true, on, 1, yes; +false: false, off, 0, no. In a config file this could look like: + + my-switch=true + my-switch=on + my-switch=1 + my-switch=yes + my-switch= + + my-switch=false + my-switch=off + my-switch=0 + my-switch=no + +*/ diff --git a/src/boost/libs/program_options/example/real.cpp b/src/boost/libs/program_options/example/real.cpp new file mode 100644 index 00000000..1c5d1322 --- /dev/null +++ b/src/boost/libs/program_options/example/real.cpp @@ -0,0 +1,96 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include +using namespace boost::program_options; + +#include +using namespace std; + +/* Auxiliary functions for checking input for validity. */ + +/* Function used to check that 'opt1' and 'opt2' are not specified + at the same time. */ +void conflicting_options(const variables_map& vm, + const char* opt1, const char* opt2) +{ + if (vm.count(opt1) && !vm[opt1].defaulted() + && vm.count(opt2) && !vm[opt2].defaulted()) + throw logic_error(string("Conflicting options '") + + opt1 + "' and '" + opt2 + "'."); +} + +/* Function used to check that of 'for_what' is specified, then + 'required_option' is specified too. */ +void option_dependency(const variables_map& vm, + const char* for_what, const char* required_option) +{ + if (vm.count(for_what) && !vm[for_what].defaulted()) + if (vm.count(required_option) == 0 || vm[required_option].defaulted()) + throw logic_error(string("Option '") + for_what + + "' requires option '" + required_option + "'."); +} + +int main(int argc, char* argv[]) +{ + try { + string ofile; + string macrofile, libmakfile; + bool t_given = false; + bool b_given = false; + string mainpackage; + string depends = "deps_file"; + string sources = "src_file"; + string root = "."; + + options_description desc("Allowed options"); + desc.add_options() + // First parameter describes option name/short name + // The second is parameter to option + // The third is description + ("help,h", "print usage message") + ("output,o", value(&ofile), "pathname for output") + ("macrofile,m", value(¯ofile), "full pathname of macro.h") + ("two,t", bool_switch(&t_given), "preprocess both header and body") + ("body,b", bool_switch(&b_given), "preprocess body in the header context") + ("libmakfile,l", value(&libmakfile), + "write include makefile for library") + ("mainpackage,p", value(&mainpackage), + "output dependency information") + ("depends,d", value(&depends), + "write dependencies to ") + ("sources,s", value(&sources), "write source package list to ") + ("root,r", value(&root), "treat as project root directory") + ; + + variables_map vm; + store(parse_command_line(argc, argv, desc), vm); + + if (vm.count("help")) { + cout << desc << "\n"; + return 0; + } + + conflicting_options(vm, "output", "two"); + conflicting_options(vm, "output", "body"); + conflicting_options(vm, "output", "mainpackage"); + conflicting_options(vm, "two", "mainpackage"); + conflicting_options(vm, "body", "mainpackage"); + + conflicting_options(vm, "two", "body"); + conflicting_options(vm, "libmakfile", "mainpackage"); + conflicting_options(vm, "libmakfile", "mainpackage"); + + option_dependency(vm, "depends", "mainpackage"); + option_dependency(vm, "sources", "mainpackage"); + option_dependency(vm, "root", "mainpackage"); + + cout << "two = " << vm["two"].as() << "\n"; + } + catch(exception& e) { + cerr << e.what() << "\n"; + } +} diff --git a/src/boost/libs/program_options/example/regex.cpp b/src/boost/libs/program_options/example/regex.cpp new file mode 100644 index 00000000..df98f77a --- /dev/null +++ b/src/boost/libs/program_options/example/regex.cpp @@ -0,0 +1,101 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This example shows how a user-defined class can be parsed using +// specific mechanism -- not the iostream operations used by default. +// +// A new class 'magic_number' is defined and the 'validate' method is overloaded +// to validate the values of that class using Boost.Regex. +// To test, run +// +// regex -m 123-456 +// regex -m 123-4567 +// +// The first invocation should output: +// +// The magic is "456" +// +// and the second invocation should issue an error message. + +#include +#include + +using namespace boost; +using namespace boost::program_options; + +#include +using namespace std; + +/* Define a completely non-sensical class. */ +struct magic_number { +public: + magic_number(int n) : n(n) {} + int n; +}; + +/* Overload the 'validate' function for the user-defined class. + It makes sure that value is of form XXX-XXX + where X are digits and converts the second group to an integer. + This has no practical meaning, meant only to show how + regex can be used to validate values. +*/ +void validate(boost::any& v, + const std::vector& values, + magic_number*, int) +{ + static regex r("\\d\\d\\d-(\\d\\d\\d)"); + + using namespace boost::program_options; + + // Make sure no previous assignment to 'a' was made. + validators::check_first_occurrence(v); + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + const string& s = validators::get_single_string(values); + + // Do regex match and convert the interesting part to + // int. + smatch match; + if (regex_match(s, match, r)) { + v = any(magic_number(lexical_cast(match[1]))); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + + +int main(int ac, char* av[]) +{ + try { + options_description desc("Allowed options"); + desc.add_options() + ("help", "produce a help screen") + ("version,v", "print the version number") + ("magic,m", value(), + "magic value (in NNN-NNN format)") + ; + + variables_map vm; + store(parse_command_line(ac, av, desc), vm); + + if (vm.count("help")) { + cout << "Usage: regex [options]\n"; + cout << desc; + return 0; + } + if (vm.count("version")) { + cout << "Version 1.\n"; + return 0; + } + if (vm.count("magic")) { + cout << "The magic is \"" + << vm["magic"].as().n << "\"\n"; + } + } + catch(std::exception& e) + { + cout << e.what() << "\n"; + } +} diff --git a/src/boost/libs/program_options/example/response_file.cpp b/src/boost/libs/program_options/example/response_file.cpp new file mode 100644 index 00000000..ce80f76a --- /dev/null +++ b/src/boost/libs/program_options/example/response_file.cpp @@ -0,0 +1,94 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** This example shows how to handle response file. + + For a test, build and run: + response_file -I foo @response_file.rsp + + The expected output is: + Include paths: foo bar biz + + Thanks to Hartmut Kaiser who raised the issue of response files + and discussed the possible approach. +*/ + + +#include +#include +#include +#include +#include +using namespace boost; +using namespace boost::program_options; + +#include +#include +using namespace std; + +// Additional command line parser which interprets '@something' as a +// option "config-file" with the value "something" +pair at_option_parser(string const&s) +{ + if ('@' == s[0]) + return std::make_pair(string("response-file"), s.substr(1)); + else + return pair(); +} + +int main(int ac, char* av[]) +{ + try { + options_description desc("Allowed options"); + desc.add_options() + ("help", "produce a help message") + ("include-path,I", value< vector >()->composing(), + "include path") + ("magic", value(), "magic value") + ("response-file", value(), + "can be specified with '@name', too") + ; + + variables_map vm; + store(command_line_parser(ac, av).options(desc) + .extra_parser(at_option_parser).run(), vm); + + if (vm.count("help")) { + cout << desc; + } + if (vm.count("response-file")) { + // Load the file and tokenize it + ifstream ifs(vm["response-file"].as().c_str()); + if (!ifs) { + cout << "Could not open the response file\n"; + return 1; + } + // Read the whole file into a string + stringstream ss; + ss << ifs.rdbuf(); + // Split the file content + char_separator sep(" \n\r"); + string sstr = ss.str(); + tokenizer > tok(sstr, sep); + vector args; + copy(tok.begin(), tok.end(), back_inserter(args)); + // Parse the file and store the options + store(command_line_parser(args).options(desc).run(), vm); + } + + if (vm.count("include-path")) { + const vector& s = vm["include-path"].as >(); + cout << "Include paths: "; + copy(s.begin(), s.end(), ostream_iterator(cout, " ")); + cout << "\n"; + } + if (vm.count("magic")) { + cout << "Magic value: " << vm["magic"].as() << "\n"; + } + } + catch (std::exception& e) { + cout << e.what() << "\n"; + } +} diff --git a/src/boost/libs/program_options/example/response_file.rsp b/src/boost/libs/program_options/example/response_file.rsp new file mode 100644 index 00000000..d7c67773 --- /dev/null +++ b/src/boost/libs/program_options/example/response_file.rsp @@ -0,0 +1,3 @@ +-I bar +-I biz +--magic 10 \ No newline at end of file diff --git a/src/boost/libs/program_options/index.html b/src/boost/libs/program_options/index.html new file mode 100644 index 00000000..66cb529e --- /dev/null +++ b/src/boost/libs/program_options/index.html @@ -0,0 +1,14 @@ + + + + + +Automatic redirection failed, please go to +../../doc/html/program_options.html
+

© Copyright Beman Dawes, 2001

+

Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy +at www.boost.org/LICENSE_1_0.txt)

+ + \ No newline at end of file diff --git a/src/boost/libs/program_options/meta/libraries.json b/src/boost/libs/program_options/meta/libraries.json new file mode 100644 index 00000000..5fbf3126 --- /dev/null +++ b/src/boost/libs/program_options/meta/libraries.json @@ -0,0 +1,15 @@ +{ + "key": "program_options", + "name": "Program Options", + "authors": [ + "Vladimir Prus" + ], + "description": "The program_options library allows program developers to obtain program options, that is (name, value) pairs from the user, via conventional methods such as command line and config file.", + "category": [ + "IO", + "Miscellaneous" + ], + "maintainers": [ + "Vladimir Prus " + ] +} diff --git a/src/boost/libs/program_options/src/cmdline.cpp b/src/boost/libs/program_options/src/cmdline.cpp new file mode 100644 index 00000000..c2cf1da1 --- /dev/null +++ b/src/boost/libs/program_options/src/cmdline.cpp @@ -0,0 +1,713 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace boost { namespace program_options { + + using namespace std; + using namespace boost::program_options::command_line_style; + + + string + invalid_syntax::get_template(kind_t kind) + { + // Initially, store the message in 'const char*' variable, + // to avoid conversion to string in all cases. + const char* msg; + switch(kind) + { + case empty_adjacent_parameter: + msg = "the argument for option '%canonical_option%' should follow immediately after the equal sign"; + break; + case missing_parameter: + msg = "the required argument for option '%canonical_option%' is missing"; + break; + case unrecognized_line: + msg = "the options configuration file contains an invalid line '%invalid_line%'"; + break; + // none of the following are currently used: + case long_not_allowed: + msg = "the unabbreviated option '%canonical_option%' is not valid"; + break; + case long_adjacent_not_allowed: + msg = "the unabbreviated option '%canonical_option%' does not take any arguments"; + break; + case short_adjacent_not_allowed: + msg = "the abbreviated option '%canonical_option%' does not take any arguments"; + break; + case extra_parameter: + msg = "option '%canonical_option%' does not take any arguments"; + break; + default: + msg = "unknown command line syntax error for '%s'"; + } + return msg; + } + + +}} + + +namespace boost { namespace program_options { namespace detail { + + // vc6 needs this, but borland chokes when this is added. +#if BOOST_WORKAROUND(_MSC_VER, < 1300) + using namespace std; + using namespace program_options; +#endif + + + cmdline::cmdline(const vector& args) + { + init(args); + } + + cmdline::cmdline(int argc, const char*const * argv) + { +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + vector args; + copy(argv+1, argv+argc+!argc, inserter(args, args.end())); + init(args); +#else + init(vector(argv+1, argv+argc+!argc)); +#endif + } + + void + cmdline::init(const vector& args) + { + this->m_args = args; + m_style = command_line_style::default_style; + m_desc = 0; + m_positional = 0; + m_allow_unregistered = false; + } + + void + cmdline::style(int style) + { + if (style == 0) + style = default_style; + + check_style(style); + this->m_style = style_t(style); + } + + void + cmdline::allow_unregistered() + { + this->m_allow_unregistered = true; + } + + void + cmdline::check_style(int style) const + { + bool allow_some_long = + (style & allow_long) || (style & allow_long_disguise); + + const char* error = 0; + if (allow_some_long && + !(style & long_allow_adjacent) && !(style & long_allow_next)) + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::long_allow_next' " + "(whitespace separated arguments) or " + "'command_line_style::long_allow_adjacent' ('=' separated arguments) for " + "long options."; + + if (!error && (style & allow_short) && + !(style & short_allow_adjacent) && !(style & short_allow_next)) + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::short_allow_next' " + "(whitespace separated arguments) or " + "'command_line_style::short_allow_adjacent' ('=' separated arguments) for " + "short options."; + + if (!error && (style & allow_short) && + !(style & allow_dash_for_short) && !(style & allow_slash_for_short)) + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::allow_slash_for_short' " + "(slashes) or 'command_line_style::allow_dash_for_short' (dashes) for " + "short options."; + + if (error) + boost::throw_exception(invalid_command_line_style(error)); + + // Need to check that if guessing and long disguise are enabled + // -f will mean the same as -foo + } + + bool + cmdline::is_style_active(style_t style) const + { + return ((m_style & style) ? true : false); + } + + void + cmdline::set_options_description(const options_description& desc) + { + m_desc = &desc; + } + + void + cmdline::set_positional_options( + const positional_options_description& positional) + { + m_positional = &positional; + } + + int + cmdline::get_canonical_option_prefix() + { + if (m_style & allow_long) + return allow_long; + + if (m_style & allow_long_disguise) + return allow_long_disguise; + + if ((m_style & allow_short) && (m_style & allow_dash_for_short)) + return allow_dash_for_short; + + if ((m_style & allow_short) && (m_style & allow_slash_for_short)) + return allow_slash_for_short; + + return 0; + } + + vector