Compare commits

...

34 Commits

Author SHA1 Message Date
Copilot
ec6794632f Move 'arg' variable to detail namespace (#151)
Closes #150.

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Vladimir Prus <vladimir.prus@gmail.com>
2025-12-04 11:07:35 +00:00
Vladimir Prus
902aaedaaa overview.xml: clarify wording 2025-09-13 10:38:35 +01:00
Marcos Simental
6b2bc88964 Fix listing typo (#130)
The paragraph lists a couple of options and expands information on each element. However,  the following explanation lists the first element, the first, the third, and the last, whereas the logic of the discussion aims to explain the listing as first, second, third, and last elements.
2025-09-13 10:36:14 +01:00
bmagistro
5fd247085c Add override on overriden functions for c++11 (#145)
Signed-off-by: Ben Magistro <koncept1@gmail.com>
2025-09-12 16:21:44 +01:00
ivanpanch
4287ba32b7 docs: correct spelling and grammar 2025-08-27 23:08:03 +01:00
Alexander Grund
fd4a02f7e9 Update Link to regression test matrix in README (#148) 2025-08-25 16:44:05 +01:00
bmagistro
18e51b74d4 Update to modern style cast (#143)
Signed-off-by: Ben Magistro <koncept1@gmail.com>
2025-08-19 13:09:23 +01:00
Peter Dimov
6ccf63be0e Merge pull request #138 from grafikrobot/modular
Add support for modular build structure.
2025-05-02 19:16:19 +03:00
Rene Rivera
96078fd217 Move include to target. 2025-04-17 09:08:04 -05:00
Rene Rivera
43f34bebc7 Bump some containers to get correct compilers. 2025-04-12 22:39:12 -05:00
Rene Rivera
fed4374934 Fix name of some containers. 2025-04-12 22:06:58 -05:00
Rene Rivera
a403a4014c Need some utils for the node20 install. 2025-04-12 21:59:05 -05:00
Rene Rivera
87c0d641fd Tweak to use mostly containers and usable nodejs20. 2025-04-12 21:40:03 -05:00
Rene Rivera
59abe72281 Use available macOS versions on GAH. 2025-04-12 20:36:24 -05:00
Rene Rivera
d35a57a156 Update build deps. 2024-08-02 22:17:56 -05:00
Rene Rivera
0cbac86ed0 Adjust doc build to avoid boost-root references. 2024-07-28 11:07:54 -05:00
Rene Rivera
f5fce8a124 Split b2 dependencies into public and private. 2024-07-26 17:32:48 -05:00
Rene Rivera
b77aeaa36b Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:23 -05:00
Rene Rivera
292b605203 Update copyright dates. 2024-07-20 22:52:04 -05:00
Rene Rivera
eff0d37026 Bump B2 require to 5.2 2024-06-14 11:33:56 -05:00
Rene Rivera
88a9672fcc Sync from upstream. 2024-06-10 21:40:14 -05:00
Lukas Friembichler
ca9ed9bd43 Typo, whitespace 2024-06-05 13:34:34 +01:00
Rene Rivera
31b0ede169 Add requires-b2 check to top-level build file. 2024-05-05 09:00:01 -05:00
Rene Rivera
80d3576414 Add missing NO_LIB usage requirements. 2024-04-28 20:16:25 -05:00
Rene Rivera
59f09593bb Sync from upstream. 2024-04-10 07:56:56 -05:00
Peter Dimov
5cf65662fb Merge branch 'master' into develop 2024-04-08 05:56:25 +03:00
Peter Dimov
d1ddaa8a0e Fix Cygwin failures 2024-04-08 03:15:51 +03:00
Peter Dimov
c832f18c08 Update appveyor.yml 2024-04-07 20:51:10 +03:00
Peter Dimov
8f848d8b75 Merge pull request #133 from Lastique/feature/fix_cxx23_nothrow
Fix C++20 incompatibility from using exception specifications
2024-04-07 20:34:34 +03:00
Andrey Semashev
1d7cceff6c Fix C++20 incompatibility from using exception specifications.
C++20 removed support for `throw()` exception specifications, so at
least clang-19 is now emitting errors on them. Replaced exception
specifications with BOOST_NOEXCEPT_OR_NOTHROW, which converts `throw()`
to `noexcept`, but keeps the code formally compatible with C++03.
2024-04-07 19:43:41 +03:00
Peter Dimov
5f233f00be Update ci.yml 2024-04-07 19:25:38 +03:00
Rene Rivera
944550e78c Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:15:59 -05:00
Rene Rivera
5fb238c49e Make the library modular usable. 2024-03-11 08:38:17 -05:00
Sylvain Joubert
fafcca13d8 Add support for std::optional (#132) 2024-03-05 22:57:52 +02:00
25 changed files with 289 additions and 199 deletions

View File

@@ -19,140 +19,173 @@ jobs:
include:
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-4.8
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-5
- toolset: gcc-6
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: g++-6
- toolset: gcc-7
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-7
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
- toolset: gcc-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: g++-10
- toolset: gcc-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:22.04
os: ubuntu-latest
install: g++-11
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
container: ubuntu:23.04
install: g++-13
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
os: ubuntu-latest
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
container: ubuntu:23.04
install: clang-16
- toolset: clang
cxxstd: "11,14,17,2a"
os: macos-11
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
os: macos-12
container: ubuntu:24.10
os: ubuntu-latest
install: clang-17
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,23"
os: macos-15
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
container:
image: ${{matrix.container}}
volumes:
- /node20217:/node20217:rw,rshared
- ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Install nodejs20glibc2.17
if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }}
run: |
set -x
apt-get update
apt-get install -y curl xz-utils
curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz
tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
- name: Setup container environment
if: matrix.container
@@ -166,6 +199,8 @@ jobs:
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- uses: actions/checkout@v4
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
@@ -227,7 +262,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@@ -264,14 +299,14 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
@@ -312,14 +347,14 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
@@ -370,14 +405,14 @@ jobs:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
@@ -430,7 +465,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@@ -479,7 +514,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
@@ -546,7 +581,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd

11
Jamfile
View File

@@ -1,11 +0,0 @@
# 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 ;

View File

@@ -14,8 +14,8 @@ Distributed under the [Boost Software License, Version 1.0](http://www.boost.org
|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)
|[`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)](https://regression.boost.io/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)](https://regression.boost.io/develop/developer/program_options.html)
### Directories

View File

@@ -1,78 +1,68 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright (C) 2017, 2018 James E. King III
# Copyright 2016-2019 Peter Dimov
# 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)
# When copying this to a new library, be sure to update the name of the library
# in two places (once each at the top of install: and test_script:)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- develop
- master
matrix:
allow_failures:
- MAYFAIL: true
- develop
- /feature\/.*/
environment:
global:
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
# see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
# to use the default for a given environment, comment it out; recommend you build debug and release however..
# on Windows it is important to exercise all the possibilities, especially shared vs static
# B2_ADDRESS_MODEL: address-model=64,32
# B2_LINK: link=shared,static
# B2_THREADING: threading=multi,single
B2_VARIANT: variant=release,debug
CXXSTD: 03
matrix:
- FLAVOR: Visual Studio 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
CXXSTD: 14,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
B2_ADDRESS_MODEL: address-model=64,32
- FLAVOR: Visual Studio 2013
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-12.0
- FLAVOR: mingw32
ARCH: i686
B2_ADDRESS_MODEL: address-model=32
SCRIPT: ci\mingw.bat
- FLAVOR: mingw64
ARCH: x86_64
B2_ADDRESS_MODEL: address-model=64
SCRIPT: ci\mingw.bat
- FLAVOR: cygwin (64-bit)
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: address-model=64
TOOLSET: gcc
MAYFAIL: true
- FLAVOR: cygwin (32-bit)
CXXSTD: 14,17,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
CXXSTD: 14,17,20,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
B2_ADDRESS_MODEL: address-model=32
TOOLSET: gcc
MAYFAIL: true
CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
TOOLSET: gcc
CXXSTD: 11,14,17,2a
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
TOOLSET: gcc
CXXSTD: 11,14,17,2a
install:
- set SELF=program_options
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update -q --init tools/boostdep
- git submodule update -q --init tools/build
- git submodule update -q --init tools/inspect
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\%SELF%
- python tools/boostdep/depinst/depinst.py --include example %SELF%
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\program_options\
- python tools/boostdep/depinst/depinst.py program_options
- cmd /c bootstrap
- b2 headers
- b2 -d0 headers
build: off
test_script:
- set SELF=program_options
- PATH=%ADDPATH%%PATH%
- IF DEFINED SCRIPT (call libs\%SELF%\%SCRIPT%) ELSE (b2 libs/%SELF% toolset=%TOOLSET% cxxstd=%CXXSTD% %CXXFLAGS% %DEFINES% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3)
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/program_options/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

32
build.jam Normal file
View File

@@ -0,0 +1,32 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/any//boost_any
/boost/config//boost_config
/boost/core//boost_core
/boost/detail//boost_detail
/boost/function//boost_function
/boost/iterator//boost_iterator
/boost/lexical_cast//boost_lexical_cast
/boost/smart_ptr//boost_smart_ptr
/boost/static_assert//boost_static_assert
/boost/throw_exception//boost_throw_exception
/boost/type_traits//boost_type_traits ;
project /boost/program_options
;
explicit
[ alias boost_program_options : build//boost_program_options ]
[ alias all : boost_program_options example test ]
;
call-if : boost-library program_options
: install boost_program_options
;

View File

@@ -1,16 +1,25 @@
project boost/program_options
: source-location ../src
constant boost_dependencies_private :
/boost/bind//boost_bind
/boost/tokenizer//boost_tokenizer
;
project
: source-location ../src
: common-requirements <include>../include <library>$(boost_dependencies)
: requirements <library>$(boost_dependencies_private)
;
SOURCES =
cmdline config_file options_description parsers variables_map
cmdline config_file options_description parsers variables_map
value_semantic positional_options utf8_codecvt_facet
convert winmain split
;
boost-lib program_options
lib boost_program_options
: $(SOURCES).cpp
: # See https://svn.boost.org/trac/boost/ticket/5049
<target-os>hpux,<toolset>gcc:<define>_INCLUDE_STDC__SOURCE_199901
;
<link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1
<define>BOOST_PROGRAM_OPTIONS_NO_LIB=1
;

View File

@@ -2,15 +2,15 @@
import toolset ;
toolset.using doxygen ;
boostbook program_option
: program_options.xml
: <implicit-dependency>autodoc
boostbook program_option
: program_options.xml
: <implicit-dependency>autodoc
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;
doxygen autodoc
: [ glob ../../../boost/program_options/*.hpp ] ;
doxygen autodoc
: [ glob ../include/boost/program_options/*.hpp ] ;
###############################################################################
alias boostdoc

View File

@@ -8,7 +8,7 @@
<section>
<title>Acknowledgements</title>
<para>I'm very gratefull to all the people who helped with the development,
<para>I'm very grateful to all the people who helped with the development,
by discussion, fixes, and as users. It was pleasant
to see all that involvement, which made the library much better than it
would be otherwise.
@@ -25,7 +25,7 @@
<para>The formal review lead to numerous comments and enhancements. Pavol
Droba helped with the option description semantic. Gennadiy Rozental has
criticised many aspects of the library which caused various simplifications.
Pavel Vozenilek did carefull review of the implementation. A number of
Pavel Vozenilek did careful review of the implementation. A number of
comments were made by:
<itemizedlist>
<listitem><para>David Abrahams</para></listitem>

View File

@@ -74,7 +74,7 @@
of the library -- ascii and Unicode.
</para>
<para>Another important point is that ascii strings are passed though
<para>Another important point is that ascii strings are passed through
without modification. In other words, it's not possible to just convert
ascii to Unicode and process the Unicode further. The problem is that the
default conversion mechanism -- the <code>codecvt</code> facet -- might
@@ -85,7 +85,7 @@
don't support Unicode option names. Unicode support is hard and
requires a Boost-wide solution. Even comparing two arbitrary Unicode
strings is non-trivial. Finally, using Unicode in option names is
related to internationalization, which has it's own
related to internationalization, which has its own
complexities. E.g. if option names depend on current locale, then all
program parts and other parts which use the name must be
internationalized too.
@@ -210,4 +210,4 @@
sgml-parent-document: ("program_options.xml" "section")
sgml-set-face: t
End:
-->
-->

View File

@@ -23,7 +23,7 @@ options groups/hidden options
<title>Non-conventional Syntax</title>
<para>Sometimes, standard command line syntaxes are not enough. For
example, the gcc compiler has "-frtti" and -fno-rtti" options, and this
example, the gcc compiler has "-frtti" and "-fno-rtti" options, and this
syntax is not directly supported.
</para>
@@ -66,7 +66,7 @@ store(command_line_parser(ac, av).options(desc).extra_parser(reg_foo)
<indexterm><primary>response files</primary></indexterm>
<para>Some operating system have very low limits of the command line
<para>Some operating systems have very low limits of the command line
length. The common way to work around those limitations is using
<firstterm>response files</firstterm>. A response file is just a
configuration file which uses the same syntax as the command line. If
@@ -304,7 +304,7 @@ void validate(boost::any& v,
for the value, and in this case is either empty or contains an instance of
the <code>magic_number</code> class. The second is the list of strings
found in the next occurrence of the option. The remaining two parameters
are needed to workaround the lack of partial template specialization and
are needed to work around the lack of partial template specialization and
partial function template ordering on some compilers.
</para>
@@ -346,7 +346,7 @@ void validate(boost::any& v,
<emphasis>some</emphasis> Unicode-aware options. They are different from
ordinary options in that they accept <code>wstring</code> input, and
process it using wide character streams. Creating an Unicode-aware option
is easy: just use the the <code>wvalue</code> function instead of the
is easy: just use the <code>wvalue</code> function instead of the
regular <code>value</code>.
</para>
@@ -379,7 +379,7 @@ locale::global(locale(""));
implementation, though. The quick test involves three steps:
<orderedlist>
<listitem>
<para>Go the the "test" directory and build the "test_convert" binary.</para>
<para>Go to the "test" directory and build the "test_convert" binary.</para>
</listitem>
<listitem>
<para>Set some non-ascii locale in the environment. On Linux, one can

View File

@@ -50,7 +50,7 @@
provides a class which stores all option values and that class can be
freely passed around your program to modules which need access to the
options. All the other components can be used only in the place where
the actual parsing is the done. However, it might also make sense for the
the actual parsing is done. However, it might also make sense for the
individual program modules to describe their options and pass them to the
main module, which will merge all options. Of course, this is only
important when the number of options is large and declaring them in one
@@ -185,9 +185,9 @@ desc.add_options()
("email", value&lt;string&gt;()->multitoken(), "email to send to")
;
</programlisting>
For the first parameter, we specify only the name and the
For the first option, we specify only the name and the
description. No value can be specified in the parsed source.
For the first option, the user must specify a value, using a single
For the second option, the user must specify a value, using a single
token. For the third option, the user may either provide a single token
for the value, or no token at all. For the last option, the value can
span several tokens. For example, the following command line is OK:
@@ -208,7 +208,7 @@ desc.add_options()
<para>The description string has one or more paragraphs, separated by
the newline character ('\n'). When an option is output, the library
will compute the indentation for options's description. Each of the
paragraph is output as a separate line with that intentation. If
paragraph is output as a separate line with that indentation. If
a paragraph does not fit on one line it is spanned over multiple
lines (which will have the same indentation).
</para>
@@ -538,7 +538,7 @@ desc.add_options()
</para>
<para>The environment variables can be parsed with the
&parse_environment; function. The function have several overloaded
&parse_environment; function. The function has several overloaded
versions. The first parameter is always an &options_description;
instance, and the second specifies what variables must be processed, and
what option names must correspond to it. To describe the second
@@ -546,13 +546,13 @@ desc.add_options()
variables.</para>
<para>If you have an option that should be specified via environment
variable, you need make up the variable's name. To avoid name clashes,
variable, you need to make up the variable's name. To avoid name clashes,
we suggest that you use a sufficiently unique prefix for environment
variables. Also, while option names are most likely in lower case,
environment variables conventionally use upper case. So, for an option
name <literal>proxy</literal> the environment variable might be called
<envar>BOOST_PROXY</envar>. During parsing, we need to perform reverse
conversion of the names. This is accomplished by passing the choosen
conversion of the names. This is accomplished by passing the chosen
prefix as the second parameter of the &parse_environment; function.
Say, if you pass <literal>BOOST_</literal> as the prefix, and there are
two variables, <envar>CVSROOT</envar> and <envar>BOOST_PROXY</envar>, the
@@ -588,7 +588,7 @@ desc.add_options()
representations that are available in C++ literals are not supported by
lexical_cast, and thus will not work with program_options.</para>
<para>Booleans a special in that there are multiple ways to come at them.
<para>Booleans are special in that there are multiple ways to come at them.
Similar to another value type, it can be specified as <code>("my-option",
value&lt;bool&gt;())</code>, and then set as:</para>
<screen>
@@ -648,7 +648,7 @@ example --other-switch
<row>
<entry>&parse_command_line;</entry>
<entry>parses command line (simpified interface)</entry>
<entry>parses command line (simplified interface)</entry>
</row>
<row>

View File

@@ -70,7 +70,7 @@
</para>
<para>
Now let's see some examples of the library usage in the <xref
Now let's see some examples of the library usage in <xref
linkend="program_options.tutorial"/>.
</para>

View File

@@ -9,7 +9,7 @@
namespace boost { namespace program_options { namespace command_line_style {
/** Various possible styles of options.
There are "long" options, which start with "--" and "short",
There are "long" options, which start with "--", and "short",
which start with either "-" or "/". Both kinds can be allowed or
disallowed, see allow_long and allow_short. The allowed character
for short options is also configurable.
@@ -51,7 +51,7 @@ namespace boost { namespace program_options { namespace command_line_style {
/** Allow to merge several short options together,
so that "-s -k" become "-sk". All of the options
but last should accept no parameter. For example, if
"-s" accept a parameter, then "k" will be taken as
"-s" accepts a parameter, then "k" will be taken as
parameter, not another short option.
Dos-style short options cannot be sticky.
*/

View File

@@ -8,18 +8,24 @@
#include <boost/throw_exception.hpp>
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
# include <optional>
#endif
// forward declaration
namespace boost { template<class T> class optional; }
namespace boost { namespace program_options {
extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
namespace detail {
extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
}
template<class T, class charT>
std::string
typed_value<T, charT>::name() const
{
std::string const& var = (m_value_name.empty() ? arg : m_value_name);
std::string const& var = (m_value_name.empty() ? detail::arg : m_value_name);
if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) {
std::string msg = "[=" + var + "(=" + m_implicit_value_as_text + ")]";
if (!m_default_value.empty() && !m_default_value_as_text.empty())
@@ -146,7 +152,7 @@ namespace boost { namespace program_options {
boost::any a;
std::vector<std::basic_string<charT> > cv;
cv.push_back(s[i]);
validate(a, cv, (T*)0, 0);
validate(a, cv, static_cast<T*>(nullptr), 0);
tv->push_back(boost::any_cast<T>(a));
}
catch(const bad_lexical_cast& /*e*/) {
@@ -165,10 +171,26 @@ namespace boost { namespace program_options {
validators::check_first_occurrence(v);
validators::get_single_string(s);
boost::any a;
validate(a, s, (T*)0, 0);
validate(a, s, static_cast<T*>(nullptr), 0);
v = boost::any(boost::optional<T>(boost::any_cast<T>(a)));
}
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
/** Validates std::optional arguments. */
template<class T, class charT>
void validate(boost::any& v,
const std::vector<std::basic_string<charT> >& s,
std::optional<T>*,
int)
{
validators::check_first_occurrence(v);
validators::get_single_string(s);
boost::any a;
validate(a, s, static_cast<T*>(nullptr), 0);
v = boost::any(std::optional<T>(boost::any_cast<T>(a)));
}
#endif
template<class T, class charT>
void
typed_value<T, charT>::
@@ -181,7 +203,7 @@ namespace boost { namespace program_options {
if (new_tokens.empty() && !m_implicit_value.empty())
value_store = m_implicit_value;
else
validate(value_store, new_tokens, (T*)0, 0);
validate(value_store, new_tokens, static_cast<T*>(nullptr), 0);
}
template<class T>

View File

@@ -11,12 +11,12 @@
namespace boost {
/** The 'eof_iterator' class is useful for constructing forward iterators
in cases where iterator extract data from some source and it's easy
in cases where the iterator extracts data from some source and it's easy
to detect 'eof' \-- i.e. the situation where there's no data. One
apparent example is reading lines from a file.
Implementing such iterators using 'iterator_facade' directly would
require to create class with three core operation, a couple of
require to create class with three core operations, a couple of
constructors. When using 'eof_iterator', the derived class should define
only one method to get new value, plus a couple of constructors.

View File

@@ -51,7 +51,7 @@ namespace boost { namespace program_options {
{}
};
/** Class thrown when there are programming error related to style */
/** Class thrown when there are programming errors related to style */
class BOOST_PROGRAM_OPTIONS_DECL BOOST_SYMBOL_VISIBLE invalid_command_line_style : public error {
public:
invalid_command_line_style(const std::string& msg)
@@ -83,7 +83,7 @@ namespace boost { namespace program_options {
* Options are displayed in "canonical" form
* This is the most unambiguous form of the
* *parsed* option name and would correspond to
* option_description::format_name()
* option_description::format_name(),
* i.e. what is shown by print_usage()
*
* The "canonical" form depends on whether the option is
@@ -183,7 +183,7 @@ namespace boost { namespace program_options {
/** Creates the error_message on the fly
* Currently a thin wrapper for substitute_placeholders() */
virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW;
virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW override;
protected:
/** Used to hold the error text returned by what() */
@@ -243,7 +243,7 @@ namespace boost { namespace program_options {
* It makes no sense to have an option name, when we can't match an option to the
* parameter
*
* Having this a part of the error_with_option_name hierachy makes error handling
* Having this as part of the error_with_option_name hierarchy makes error handling
* a lot easier, even if the name indicates some sort of conceptual dissonance!
*
* */
@@ -256,7 +256,7 @@ namespace boost { namespace program_options {
}
/** Does NOT set option name, because no option name makes sense */
virtual void set_option_name(const std::string&) {}
virtual void set_option_name(const std::string&) override {}
BOOST_DEFAULTED_FUNCTION(~error_with_no_option_name() BOOST_NOEXCEPT_OR_NOTHROW, {})
};
@@ -275,7 +275,7 @@ namespace boost { namespace program_options {
/** Class thrown when there's ambiguity amoung several possible options. */
/** Class thrown when there's ambiguity among several possible options. */
class BOOST_PROGRAM_OPTIONS_DECL BOOST_SYMBOL_VISIBLE ambiguous_option : public error_with_no_option_name {
public:
ambiguous_option(const std::vector<std::string>& xalternatives)
@@ -289,7 +289,7 @@ namespace boost { namespace program_options {
protected:
/** Makes all substitutions using the template */
virtual void substitute_placeholders(const std::string& error_template) const;
virtual void substitute_placeholders(const std::string& error_template) const override;
private:
// TODO: copy ctor might throw
std::vector<std::string> m_alternatives;
@@ -343,7 +343,7 @@ namespace boost { namespace program_options {
BOOST_DEFAULTED_FUNCTION(~invalid_config_file_syntax() BOOST_NOEXCEPT_OR_NOTHROW, {})
/** Convenience functions for backwards compatibility */
virtual std::string tokens() const {return m_substitutions.find("invalid_line")->second; }
virtual std::string tokens() const override {return m_substitutions.find("invalid_line")->second; }
};

View File

@@ -105,7 +105,7 @@ namespace program_options {
/** Returns the canonical name for the option description to enable the user to
recognised a matching option.
recognise a matching option.
1) For short options ('-', '/'), returns the short name prefixed.
2) For long options ('--' / '-') returns the first long name prefixed
3) All other cases, returns the first long name (if present) or the short

View File

@@ -30,7 +30,7 @@ namespace boost { namespace program_options {
/** Results of parsing an input source.
The primary use of this class is passing information from parsers
component to value storage component. This class does not makes
component to value storage component. This class does not make
much sense itself.
*/
template<class charT>
@@ -48,7 +48,7 @@ namespace boost { namespace program_options {
const options_description* description;
/** Mainly used for the diagnostic messages in exceptions.
* The canonical option prefix for the parser which generated these results,
* The canonical option prefix for the parser which generated these results,
* depending on the settings for basic_command_line_parser::style() or
* cmdline::style(). In order of precedence of command_line_style enums:
* allow_long
@@ -77,7 +77,7 @@ namespace boost { namespace program_options {
basic_parsed_options<char> utf8_encoded_options;
/** Mainly used for the diagnostic messages in exceptions.
* The canonical option prefix for the parser which generated these results,
* The canonical option prefix for the parser which generated these results,
* depending on the settings for basic_command_line_parser::style() or
* cmdline::style(). In order of precedence of command_line_style enums:
* allow_long
@@ -150,7 +150,7 @@ namespace boost { namespace program_options {
instance of basic_option<charT> will be added to result,
with 'unrecognized' field set to 'true'. It's possible to
collect all unrecognized options with the 'collect_unrecognized'
funciton.
function.
*/
basic_command_line_parser& allow_unregistered();
@@ -214,7 +214,7 @@ namespace boost { namespace program_options {
/** Collects the original tokens for all named options with
'unregistered' flag set. If 'mode' is 'include_positional'
also collects all positional options.
Returns the vector of origianl tokens for all collected
Returns the vector of original tokens for all collected
options.
*/
template<class charT>
@@ -254,8 +254,8 @@ namespace boost { namespace program_options {
/** Splits a given string to a collection of single strings which
can be passed to command_line_parser. The second parameter is
used to specify a collection of possible seperator chars used
for splitting. The seperator is defaulted to space " ".
used to specify a collection of possible separator chars used
for splitting. The separator is defaulted to space " ".
Splitting is done in a unix style way, with respect to quotes '"'
and escape characters '\'
*/

View File

@@ -37,7 +37,7 @@ namespace boost { namespace program_options {
public:
positional_options_description();
/** Species that up to 'max_count' next positional options
/** Specifies that up to 'max_count' next positional options
should be given the 'name'. The value of '-1' means 'unlimited'.
No calls to 'add' can be made after call with 'max_value' equal to
'-1'.

View File

@@ -51,7 +51,7 @@ namespace boost { namespace program_options {
/** Parses a group of tokens that specify a value of option.
Stores the result in 'value_store', using whatever representation
is desired. May be be called several times if value of the same
is desired. May be called several times if value of the same
option is specified more than once.
*/
virtual void parse(boost::any& value_store,
@@ -71,7 +71,7 @@ namespace boost { namespace program_options {
virtual ~value_semantic() {}
};
/** Helper class which perform necessary character conversions in the
/** Helper class which performs necessary character conversions in the
'parse' method and forwards the data further.
*/
template<class charT>
@@ -92,7 +92,7 @@ namespace boost { namespace program_options {
private: // base overrides
void parse(boost::any& value_store,
const std::vector<std::string>& new_tokens,
bool utf8) const;
bool utf8) const override;
protected: // interface for derived classes.
virtual void xparse(boost::any& value_store,
const std::vector<std::string>& new_tokens)
@@ -112,7 +112,7 @@ namespace boost { namespace program_options {
private: // base overrides
void parse(boost::any& value_store,
const std::vector<std::string>& new_tokens,
bool utf8) const;
bool utf8) const override;
protected: // interface for derived classes.
#if !defined(BOOST_NO_STD_WSTRING)
virtual void xparse(boost::any& value_store,
@@ -130,34 +130,34 @@ namespace boost { namespace program_options {
: m_zero_tokens(zero_tokens)
{}
std::string name() const;
std::string name() const override;
unsigned min_tokens() const;
unsigned max_tokens() const;
unsigned min_tokens() const override;
unsigned max_tokens() const override;
bool is_composing() const { return false; }
bool is_composing() const override { return false; }
bool is_required() const { return false; }
bool is_required() const override { return false; }
/** If 'value_store' is already initialized, or new_tokens
has more than one elements, throws. Otherwise, assigns
has more than one element, throws. Otherwise, assigns
the first string from 'new_tokens' to 'value_store', without
any modifications.
*/
void xparse(boost::any& value_store,
const std::vector<std::string>& new_tokens) const;
const std::vector<std::string>& new_tokens) const override;
/** Does nothing. */
bool apply_default(boost::any&) const { return false; }
bool apply_default(boost::any&) const override { return false; }
/** Does nothing. */
void notify(const boost::any&) const {}
void notify(const boost::any&) const override {}
private:
bool m_zero_tokens;
};
#ifndef BOOST_NO_RTTI
/** Base class for all option that have a fixed type, and are
/** Base class for all options that have a fixed type, and are
willing to announce this type to the outside world.
Any 'value_semantics' for which you want to find out the
type can be dynamic_cast-ed to typed_value_base. If conversion
@@ -218,7 +218,7 @@ namespace boost { namespace program_options {
/** Specifies an implicit value, which will be used
if the option is given, but without an adjacent value.
Using this implies that an explicit value is optional,
Using this implies that an explicit value is optional.
*/
typed_value* implicit_value(const T &v)
{
@@ -228,7 +228,7 @@ namespace boost { namespace program_options {
return this;
}
/** Specifies the name used to to the value in help message. */
/** Specifies the name used for the value in the help message. */
typed_value* value_name(const std::string& name)
{
m_value_name = name;
@@ -278,7 +278,7 @@ namespace boost { namespace program_options {
}
/** Specifies that no tokens may be provided as the value of
this option, which means that only presense of the option
this option, which means that only presence of the option
is significant. For such option to be useful, either the
'validate' function should be specialized, or the
'implicit_value' method should be also used. In most
@@ -299,11 +299,11 @@ namespace boost { namespace program_options {
public: // value semantic overrides
std::string name() const;
std::string name() const override;
bool is_composing() const { return m_composing; }
bool is_composing() const override { return m_composing; }
unsigned min_tokens() const
unsigned min_tokens() const override
{
if (m_zero_tokens || !m_implicit_value.empty()) {
return 0;
@@ -312,7 +312,7 @@ namespace boost { namespace program_options {
}
}
unsigned max_tokens() const {
unsigned max_tokens() const override {
if (m_multitoken) {
return std::numeric_limits<unsigned>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
} else if (m_zero_tokens) {
@@ -322,19 +322,19 @@ namespace boost { namespace program_options {
}
}
bool is_required() const { return m_required; }
bool is_required() const override { return m_required; }
/** Creates an instance of the 'validator' class and calls
its operator() to perform the actual conversion. */
void xparse(boost::any& value_store,
const std::vector< std::basic_string<charT> >& new_tokens)
const;
const override;
/** If default value was specified via previous call to
'default_value', stores that value into 'value_store'.
Returns true if default value was stored.
*/
virtual bool apply_default(boost::any& value_store) const
virtual bool apply_default(boost::any& value_store) const override
{
if (m_default_value.empty()) {
return false;
@@ -347,12 +347,12 @@ namespace boost { namespace program_options {
/** If an address of variable to store value was specified
when creating *this, stores the value there. Otherwise,
does nothing. */
void notify(const boost::any& value_store) const;
void notify(const boost::any& value_store) const override;
public: // typed_value_base overrides
#ifndef BOOST_NO_RTTI
const std::type_info& value_type() const
const std::type_info& value_type() const override
{
return typeid(T);
}

View File

@@ -62,7 +62,7 @@ namespace boost { namespace program_options {
: v(xv), m_defaulted(xdefaulted)
{}
/** If stored value if of type T, returns that value. Otherwise,
/** If stored value is of type T, returns that value. Otherwise,
throws boost::bad_any_cast exception. */
template<class T>
const T& as() const {
@@ -138,7 +138,7 @@ namespace boost { namespace program_options {
const abstract_variables_map* m_next;
};
/** Concrete variables map which store variables in real map.
/** Concrete variables map which stores variables in real map.
This class is derived from std::map<std::string, variable_value>,
so you can use all map operators to examine its content.
@@ -162,7 +162,7 @@ namespace boost { namespace program_options {
private:
/** Implementation of abstract_variables_map::get
which does 'find' in *this. */
const variable_value& get(const std::string& name) const;
const variable_value& get(const std::string& name) const override;
/** Names of option with 'final' values \-- which should not
be changed by subsequence assignments. */

View File

@@ -84,12 +84,14 @@ namespace boost { namespace program_options {
}
#endif
BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg");
namespace detail {
BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg");
}
std::string
untyped_value::name() const
{
return arg;
return detail::arg;
}
unsigned

View File

@@ -38,7 +38,7 @@ test-suite program_options :
[ run options_description_test.cpp : : : <rtti>off : options_description_no_rtti_test ]
;
exe test_convert : test_convert.cpp ;
exe test_convert : test_convert.cpp /boost/timer//boost_timer ;
# `quick` target (for CI)
run quick.cpp : --path=initial ;

View File

@@ -7,6 +7,9 @@ namespace po = boost::program_options;
#include <boost/optional.hpp>
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
# include <optional>
#endif
#include <string>
#include "minitest.hpp"
@@ -19,9 +22,10 @@ std::vector<std::string> sv(const char* array[], unsigned size)
return r;
}
template<template<typename> class OptionalType>
void test_optional()
{
boost::optional<int> foo, bar, baz;
OptionalType<int> foo, bar, baz;
po::options_description desc;
desc.add_options()
@@ -48,6 +52,9 @@ void test_optional()
int main(int, char*[])
{
test_optional();
test_optional<boost::optional>();
#ifndef BOOST_NO_CXX17_HDR_OPTIONAL
test_optional<std::optional>();
#endif
return 0;
}

View File

@@ -300,6 +300,10 @@ void test_config_file(const char* config_file)
check_value(a2[6], "m1.v3", "3");
}
#if defined(__CYGWIN__)
extern "C" int putenv (char *__string);
#endif
void test_environment()
{
options_description desc;
@@ -308,7 +312,7 @@ void test_environment()
("bar", new untyped_value, "")
;
#if (defined(_WIN32) && ! defined(BOOST_BORLANDC) && ! defined(BOOST_EMBTC)) || (defined(__CYGWIN__))
#if defined(_WIN32) && ! defined(BOOST_BORLANDC) && ! defined(BOOST_EMBTC)
_putenv("PO_TEST_FOO=1");
#else
putenv(const_cast<char*>("PO_TEST_FOO=1"));