Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Flamefire committed Feb 21, 2025
2 parents 72429c3 + 64f1eee commit 105ac5c
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 132 deletions.
6 changes: 3 additions & 3 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
GENERATOR: Visual Studio 16 2019
configuration: Debug
BOOST_ROOT: C:\Libraries\boost_1_77_0
BOOST_ROOT: C:\Libraries\boost_1_85_0
COVERITY_SCAN_TOKEN:
secure: FzhGUr+AR/VOBGUta7dDLMDruolChnvyMSvsM/zLvPY=
COVERITY_SCAN_NOTIFICATION_EMAIL:
Expand Down Expand Up @@ -177,7 +177,7 @@ for:
- mkdir __build_cmake_test__
- cd __build_cmake_test__
- cmake -G "%GENERATOR%" -DCMAKE_CXX_STANDARD=%CXXSTD% %CMAKE_FLAGS% -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% ..
build_script: cmake --build . --config %configuration% --parallel 4
build_script: cmake --build . --config %configuration% --parallel 4 --target tests
test_script:
- ctest --output-on-failure -C %configuration% --parallel 4
- ps: |
Expand All @@ -204,7 +204,7 @@ for:
- cmake -G "%GENERATOR%" ..
- ps: |
cov-configure --msvc
cov-build --dir cov-int cmake --build . --config $env:configuration
cov-build --dir cov-int cmake --build . --target tests --config $env:configuration
If ($LastExitCode -ne 0) {
cat cov-int/build-log.txt
$host.SetShouldExit($LastExitCode)
Expand Down
189 changes: 114 additions & 75 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

30 changes: 18 additions & 12 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019 - 2022 Alexander Grund
# Copyright 2019 - 2024 Alexander Grund
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt

Expand Down Expand Up @@ -48,10 +48,10 @@ jobs:
DEP_DIR: ${{github.workspace}}/dependencies
BOOST_VERSION: 1.56.0
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Sanity check version
run: grep -E 'set\(_version [0-9]' CMakeLists.txt
- uses: actions/cache@v1
- uses: actions/cache@v4
id: cache-boost
with:
path: ${{env.DEP_DIR}}
Expand All @@ -64,7 +64,7 @@ jobs:
if: matrix.standalone == 'Boost'
run: echo "BOOST_ROOT=${DEP_DIR//\\/\/}/boost_${BOOST_VERSION//./_}" >> $GITHUB_ENV
# Install Boost
- uses: actions/checkout@v3
- uses: actions/checkout@v4
if: matrix.standalone == 'Boost' && steps.cache-boost.outputs.cache-hit != 'true'
with:
repository: boostorg/boost
Expand Down Expand Up @@ -102,18 +102,24 @@ jobs:
extraFlags="$extraFlags -DCMAKE_CXX_FLAGS=-Wundef"
fi
cmake -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -DBUILD_SHARED_LIBS=${{matrix.shared_lib}} -G "${{matrix.generator}}" $extraFlags ..
- name: Build & Install
run: cmake --build build --config ${{matrix.buildType}} --target install
- name: Build
run: cmake --build build --config ${{matrix.buildType}} --target tests

# Run test with both bash and powershell and watch for "Using std::cin" on bash but not on powershell
- name: Test
working-directory: build
run: ctest --output-on-failure -C ${{matrix.buildType}} --verbose
run: |
# The bash shell adds an incompatible PATH for MinGW: https://github.com/actions/runner-images/issues/11102
[[ "${{runner.os}}" != 'Windows' ]] || export PATH="/c/mingw64/bin:$PATH"
ctest --output-on-failure -C ${{matrix.buildType}} --verbose
- name: Test on PowerShell
working-directory: build
shell: powershell
if: runner.os == 'Windows'
run: ctest --output-on-failure -C ${{matrix.buildType}} --verbose

- name: Install
run: cmake --build build --config ${{matrix.buildType}} --target install
- name: Test consumption
working-directory: build
run: |
Expand All @@ -125,7 +131,7 @@ jobs:
CreateDocuTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Create documentation
run: |
sudo apt-get install -y doxygen
Expand All @@ -134,9 +140,9 @@ jobs:
CreateBoostDocuTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Fetch Boost.CI
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: boostorg/boost-ci
ref: master
Expand All @@ -153,8 +159,8 @@ jobs:
CheckFormatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.11
- uses: actions/checkout@v4
- uses: DoozyX/clang-format-lint-action@v0.18
with:
exclude: './doc'
clangFormatVersion: 10
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
DEP_DIR: ${{github.workspace}}/dependencies
BOOST_VERSION: 1.56.0
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Extract tag name
id: get_tag
run: |
Expand Down Expand Up @@ -56,8 +56,9 @@ jobs:
src_dir="$PWD/nowide_standalone_${{steps.get_tag.outputs.tag}}"
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/../install "$src_dir"
cmake --build . --config Debug --target install
cmake --build . --config Debug --target tests
ctest --output-on-failure -C Debug --verbose
cmake --build . --config Debug --target install
- name: Create Boost version
run: |
Expand All @@ -75,8 +76,9 @@ jobs:
src_dir="$PWD/nowide_${{steps.get_tag.outputs.tag}}"
mkdir build && cd build
cmake -DBoost_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${{runner.workspace}}/../install "$src_dir"
cmake --build . --config Debug --target install
cmake --build . --config Debug --target tests
ctest --output-on-failure -C Debug --verbose
cmake --build . --config Debug --target install
- name: Create Release
if: github.event_name == 'push'
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Branch | Appveyor | Github | codecov.io | Deps | Docs | Tests |
------------|----------|--------|------------| ---- | ---- | ----- |
[master](https://github.com/boostorg/nowide/tree/master) | [![Build status](https://ci.appveyor.com/api/projects/status/w5sywrekwd66say4/branch/master?svg=true)](https://ci.appveyor.com/project/Flamefire/nowide-fr98b/branch/master) | ![](https://github.com/boostorg/nowide/workflows/CI%20Tests/badge.svg?branch=master) ![](https://github.com/boostorg/nowide/workflows/POSIX/badge.svg?branch=master) | [![codecov](https://codecov.io/gh/boostorg/nowide/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/nowide/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/nowide.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/nowide/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://www.boost.org/development/tests/master/developer/nowide.html)
[develop](https://github.com/boostorg/nowide/tree/develop) | [![Build status](https://ci.appveyor.com/api/projects/status/w5sywrekwd66say4/branch/develop?svg=true)](https://ci.appveyor.com/project/Flamefire/nowide-fr98b/branch/develop) | ![](https://github.com/boostorg/nowide/workflows/CI%20Tests/badge.svg?branch=develop) ![](https://github.com/boostorg/nowide/workflows/POSIX/badge.svg?branch=develop) | [![codecov](https://codecov.io/gh/boostorg/nowide/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/nowide/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/nowide.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/nowide/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://www.boost.org/development/tests/develop/developer/nowide.html)
[master](https://github.com/boostorg/nowide/tree/master) | [![Build status](https://ci.appveyor.com/api/projects/status/w5sywrekwd66say4/branch/master?svg=true)](https://ci.appveyor.com/project/Flamefire/nowide-fr98b/branch/master) | [![Build status](https://github.com/boostorg/nowide/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/nowide/actions/workflows/ci.yml) | [![codecov](https://codecov.io/gh/boostorg/nowide/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/nowide/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/nowide.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/nowide/index.html) | [![Tests](https://img.shields.io/badge/tests-master-brightgreen.svg)](https://www.boost.org/development/tests/master/developer/nowide.html)
[develop](https://github.com/boostorg/nowide/tree/develop) | [![Build status](https://ci.appveyor.com/api/projects/status/w5sywrekwd66say4/branch/develop?svg=true)](https://ci.appveyor.com/project/Flamefire/nowide-fr98b/branch/develop) | [![Build status](https://github.com/boostorg/nowide/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/nowide/actions/workflows/ci.yml) | [![codecov](https://codecov.io/gh/boostorg/nowide/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/nowide/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/nowide.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/nowide/index.html) | [![Tests](https://img.shields.io/badge/tests-develop-brightgreen.svg)](https://www.boost.org/development/tests/develop/developer/nowide.html)

Quality checks:
[![Coverity Scan Build Status](https://scan.coverity.com/projects/20464/badge.svg)](https://scan.coverity.com/projects/boostorg-nowide)
Expand Down
6 changes: 5 additions & 1 deletion doc/changelog.dox
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2019-2023 Alexander Grund
// Copyright (c) 2019-2024 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
Expand All @@ -8,6 +8,10 @@

\section changelog Changelog

\subsection changelog_11_3_1 Nowide 11.3.1 (Boost 1.88)
- Fix redefinition of `_CRT_SECURE_NO_WARNINGS`
- Make `getenv` thread-safe

\subsection changelog_11_3_0 Nowide 11.3.0 (Boost 1.82)
- Add `convert_string` overload accepting a string
- Add `quoted` to output (quoted) paths (std::filesystem or boost::filesystem)
Expand Down
8 changes: 4 additions & 4 deletions doc/main.dox
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Since April 2018 there is a (Beta) function available in Windows 10 to use UTF-8

Both methods do work but have a major drawback: They are not fully reliable for the app developer.
The code page via manifest method falls back to a legacy code page when an older Windows version than 1903 is used.
Hence it is only usable if the targetted system is Windows 10 after May 2019.
Hence it is only usable if the targeted system is Windows 10 after May 2019.
The second method relies on user interaction prior to starting the program.
Obviously this is not reliable when expecting only UTF-8 in the code.

Expand Down Expand Up @@ -243,7 +243,7 @@ and temporarily replaces the original \c argv (and optionally \c env) with point
UTF-8 strings for the lifetime of the instance.
- \c boost::nowide::ifstream converts the passed filename (which is now valid UTF-8) to UTF-16
and calls the Windows Wide API to open the file stream which can then be used as usual.
- Similarily \c boost::nowide::cerr and \c boost::nowide::cout use an underlying stream buffer
- Similarly \c boost::nowide::cerr and \c boost::nowide::cout use an underlying stream buffer
that converts the UTF-8 string to UTF-16 and use another Wide API function to write it to console.

\subsection using_custom Custom API
Expand Down Expand Up @@ -289,7 +289,7 @@ before including any of the Boost.Nowide headers
\subsection using_integration Integration with Boost.Filesystem

Boost.Filesystem supports selection of narrow encoding.
Unfortunatelly the default narrow encoding on Windows isn't UTF-8.
Unfortunately the default narrow encoding on Windows isn't UTF-8.
But you can enable UTF-8 as default encoding on Boost.Filesystem by calling
`boost::nowide::nowide_filesystem()` in the beginning of your program which
imbues a locale with a UTF-8 conversion facet to convert between \c char and \c wchar_t.
Expand All @@ -300,7 +300,7 @@ used as the storage format.

For `std::filesystem::path` available since C++17 there is no way to imbue a locale.
However the `u8string()` member function can be used to obtain an UTF-8 encoded string from a `path`.
And to optain a `path` from an UTF-8 encoded string you may use `std::filesystem::u8path`
And to obtain a `path` from an UTF-8 encoded string you may use `std::filesystem::u8path`
or since C++20 one of the `path` constructors taking a `char8_t`-type input.

To read/write `std::filesystem::path` instances from/to streams you'd usually use e.g. `os << path`.
Expand Down
7 changes: 6 additions & 1 deletion include/boost/nowide/cstdlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ namespace nowide {
///
/// \brief UTF-8 aware getenv. Returns 0 if the variable is not set.
///
/// This function is not thread safe or reenterable as defined by the standard library
/// The string pointed to shall not be modified by the program.
/// This function is thread-safe as long as no other thread modifies the host environment.
/// However subsequent calls to this function might overwrite the string pointed to.
///
/// Warning: The returned pointer might only be valid for as long as the calling thread is alive.
/// So avoid passing it across thread boundaries.
///
BOOST_NOWIDE_DECL char* getenv(const char* key);

Expand Down
2 changes: 1 addition & 1 deletion include/boost/nowide/detail/is_path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace nowide {

static constexpr bool value = decltype(test<T>(0))::value;
};
/// SFINAE trait which has a member "type = Result" if the Path is a *\::filesystem::path
/// SFINAE trait/alias which resolves to Result if the Path is a *\::filesystem::path
template<typename Path, typename Result>
using enable_if_path_t = typename std::enable_if<is_path<Path>::value, Result>::type;

Expand Down
8 changes: 7 additions & 1 deletion include/boost/nowide/iostream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ namespace nowide {
class BOOST_NOWIDE_DECL winconsole_ostream : public std::ostream
{
public:
winconsole_ostream(bool isBuffered, winconsole_ostream* tieStream);
enum class target_stream
{
output,
error,
log,
};
winconsole_ostream(target_stream target, bool isBuffered, winconsole_ostream* tieStream);
~winconsole_ostream();

private:
Expand Down
2 changes: 1 addition & 1 deletion include/boost/nowide/quoted.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace nowide {
/// has the effect as-if `in >> std::quoted(path.native())` was used if that would be valid.
/// To that effect a temporary string is used, which on success is assigned to `path`.
///
/// Will automatically convert between the streams `char_type` and `path::value_type` if neccessary.
/// Will automatically convert between the streams `char_type` and `path::value_type` if necessary.
template<class Path>
#ifdef BOOST_NOWIDE_DOXYGEN
unspecified_type
Expand Down
39 changes: 37 additions & 2 deletions src/cstdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,46 @@ namespace nowide {
#include <vector>
#include <windows.h>

namespace {
// thread_local was broken on MinGW for all 32bit compiler releases prior to 11.x, see
// https://sourceforge.net/p/mingw-w64/bugs/527/
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
// Using a non-trivial destructor causes program termination on thread exit.
#if defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__clang__) && (__GNUC__ < 11)
class stackstring_for_thread
{
union
{
boost::nowide::stackstring s_;
};

public:
stackstring_for_thread() : s_(){};
// Empty destructor so the union member (using a non-trivial destructor) does not get destroyed.
// This will leak memory if any is allocated by the stackstring for each terminated thread
// but as most values fit into the stack buffer this is rare and still better than a crash.
~stackstring_for_thread(){};
void convert(const wchar_t* begin, const wchar_t* end)
{
s_.convert(begin, end);
}

char* get()
{
return s_.get();
}
};
#else
using stackstring_for_thread = boost::nowide::stackstring;
#endif

} // namespace

namespace boost {
namespace nowide {
char* getenv(const char* key)
{
static stackstring value;
thread_local stackstring_for_thread value;

const wshort_stackstring name(key);

Expand All @@ -72,7 +107,7 @@ namespace nowide {
return 0;
ptr = &tmp[0];
}
value.convert(ptr);
value.convert(ptr, ptr + n);
return value.get();
}

Expand Down
38 changes: 22 additions & 16 deletions src/iostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,32 @@ namespace nowide {
}
};

winconsole_ostream::winconsole_ostream(const bool isBuffered, winconsole_ostream* tieStream) : std::ostream(0)
winconsole_ostream::winconsole_ostream(const target_stream target,
const bool isBuffered,
winconsole_ostream* tieStream) :
std::ostream(nullptr)
{
HANDLE h;
if(isBuffered)
h = GetStdHandle(STD_OUTPUT_HANDLE);
else
h = GetStdHandle(STD_ERROR_HANDLE);
const HANDLE h = GetStdHandle(target == target_stream::output ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);

if(is_atty_handle(h))
{
d.reset(new console_output_buffer(h));
std::ostream::rdbuf(d.get());
rdbuf(d.get());
} else
{
std::ostream::rdbuf(isBuffered ? std::cout.rdbuf() : std::cerr.rdbuf());
assert(rdbuf());
switch(target)
{
case target_stream::error: rdbuf(std::cerr.rdbuf()); break;
case target_stream::log: rdbuf(std::clog.rdbuf()); break;
case target_stream::output: rdbuf(std::cout.rdbuf()); break;
}
}
assert(rdbuf());

if(tieStream)
{
tie(tieStream);
setf(ios_base::unitbuf); // If tieStream is set, this is cerr -> set unbuffered
}
if(!isBuffered)
setf(ios_base::unitbuf);
}
winconsole_ostream::~winconsole_ostream()
{
Expand Down Expand Up @@ -134,7 +139,7 @@ namespace nowide {

} // namespace detail

// Make sure those are initialized as early as possible
// Make sure those are initialized as early as possible
#ifdef BOOST_MSVC
#pragma warning(disable : 4073)
#pragma init_seg(lib)
Expand All @@ -144,10 +149,11 @@ namespace nowide {
#else
#define BOOST_NOWIDE_INIT_PRIORITY
#endif
detail::winconsole_ostream cout BOOST_NOWIDE_INIT_PRIORITY(true, nullptr);
using target_stream = detail::winconsole_ostream::target_stream;
detail::winconsole_ostream cout BOOST_NOWIDE_INIT_PRIORITY(target_stream::output, true, nullptr);
detail::winconsole_istream cin BOOST_NOWIDE_INIT_PRIORITY(&cout);
detail::winconsole_ostream cerr BOOST_NOWIDE_INIT_PRIORITY(false, &cout);
detail::winconsole_ostream clog BOOST_NOWIDE_INIT_PRIORITY(false, nullptr);
detail::winconsole_ostream cerr BOOST_NOWIDE_INIT_PRIORITY(target_stream::error, false, &cout);
detail::winconsole_ostream clog BOOST_NOWIDE_INIT_PRIORITY(target_stream::log, true, nullptr);
} // namespace nowide
} // namespace boost

Expand Down
Loading

0 comments on commit 105ac5c

Please sign in to comment.