Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1922c8f2b4 | ||
|
|
266d23c9b4 | ||
|
|
381829c2c1 | ||
|
|
f64d7e3130 | ||
|
|
64a428f622 | ||
|
|
a9df4d1bb3 | ||
|
|
c195f66709 | ||
|
|
a09708a487 | ||
|
|
02ef1186d6 | ||
|
|
962fd25b25 | ||
|
|
f7cdd17584 | ||
|
|
e5df7dd77f | ||
|
|
c5ca4f569d | ||
|
|
76a2024e13 | ||
|
|
4b8029a55c | ||
|
|
74700b2c04 | ||
|
|
7d16bc814c | ||
|
|
1f56d0f745 | ||
|
|
87f735237b | ||
|
|
e7b4ab950a | ||
|
|
3b85d48cf1 | ||
|
|
089194ddaf | ||
|
|
7631f72651 | ||
|
|
b62203a4b6 | ||
|
|
fd8b46f79b | ||
|
|
bf5cd2d3b1 | ||
|
|
22839311d1 | ||
|
|
cce54a1bcb | ||
|
|
e8e34d02a6 | ||
|
|
5a0840a737 | ||
|
|
281419de2f | ||
|
|
9bfc0b94ec | ||
|
|
b9b2a2eb46 | ||
|
|
4af4a86520 | ||
|
|
8c0f1738fc | ||
|
|
20dac44746 | ||
|
|
3670fab511 | ||
|
|
851abee07a | ||
|
|
8d1bdb2e43 | ||
|
|
c2de99deb4 | ||
|
|
f38e93591b |
@@ -0,0 +1,225 @@
|
||||
# simple ci config the idea is to use the latest ubuntu, macos, and windows that github runners give us
|
||||
# test a few different compilers (gcc/clang) in debug and release
|
||||
# and run our tests via ctest
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
# Jobs are skipped when ONLY Markdown (*.md) files are changed
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
name: '${{ matrix.os }} / ${{ matrix.build-type }} / ${{ matrix.compiler-desc }} '
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
build: [1, 2, 3, 4]
|
||||
include:
|
||||
# -------------------------------------------------------------------
|
||||
# CLANG, Release
|
||||
# -------------------------------------------------------------------
|
||||
- build: 1
|
||||
build-type: Release
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-compiler: clang++
|
||||
cxx-flags: ''
|
||||
cc-compiler: clang
|
||||
compiler-desc: clang
|
||||
os: ubuntu-latest
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# CLANG, Debug
|
||||
# -------------------------------------------------------------------
|
||||
- build: 2
|
||||
build-type: Debug
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-compiler: clang++
|
||||
cxx-flags: ''
|
||||
cc-compiler: clang
|
||||
compiler-desc: clang
|
||||
os: ubuntu-latest
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# gcc, Release
|
||||
# -------------------------------------------------------------------
|
||||
- build: 3
|
||||
build-type: Release
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-compiler: g++
|
||||
cxx-flags: ''
|
||||
cc-compiler: gcc
|
||||
compiler-desc: gcc
|
||||
os: ubuntu-latest
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# gcc, Debug
|
||||
# -------------------------------------------------------------------
|
||||
- build: 4
|
||||
build-type: Debug
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-compiler: g++
|
||||
cxx-flags: ''
|
||||
cc-compiler: gcc
|
||||
compiler-desc: gcc
|
||||
os: ubuntu-latest
|
||||
|
||||
env:
|
||||
CXX: ${{ matrix.cxx-compiler }}
|
||||
CC: ${{ matrix.cc-compiler }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Create build directories
|
||||
run: |
|
||||
mkdir _install
|
||||
mkdir _build
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/_install \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
-DCMAKE_CXX_STANDARD=${{ matrix.cxx-standard }} \
|
||||
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
|
||||
working-directory: _build
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build . \
|
||||
--config ${{ matrix.build-type }}
|
||||
working-directory: _build
|
||||
- name: Test
|
||||
run: |
|
||||
ctest --build-config ${{ matrix.build-type }} --verbose
|
||||
working-directory: _build
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# macOS
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
macos:
|
||||
name: '${{ matrix.os }} / ${{ matrix.build-type }}'
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
build: [1, 2]
|
||||
include:
|
||||
|
||||
# Release
|
||||
- build: 1
|
||||
build-type: Release
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-flags: ''
|
||||
os: macos-latest
|
||||
|
||||
# Debug
|
||||
- build: 2
|
||||
build-type: Debug
|
||||
build-shared: 'ON'
|
||||
build-docs: 'OFF'
|
||||
cxx-standard: 17
|
||||
cxx-flags: ''
|
||||
os: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Create build directories
|
||||
run: |
|
||||
mkdir _install
|
||||
mkdir _build
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake ../. \
|
||||
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/_install \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
-DCMAKE_CXX_STANDARD=${{ matrix.cxx-standard }} \
|
||||
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
|
||||
working-directory: _build
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build . \
|
||||
--config ${{ matrix.build-type }} \
|
||||
working-directory: _build
|
||||
- name: Test
|
||||
run: |
|
||||
ctest --build-config ${{ matrix.build-type }} --verbose
|
||||
working-directory: _build
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Windows
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
windows:
|
||||
name: '${{ matrix.os }} / ${{ matrix.build-type }}'
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
build: [1, 2]
|
||||
include:
|
||||
|
||||
# Release
|
||||
- build: 1
|
||||
build-type: Release
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-flags: ''
|
||||
os: windows-latest
|
||||
|
||||
# Debug
|
||||
- build: 2
|
||||
build-type: Debug
|
||||
build-shared: 'ON'
|
||||
cxx-standard: 17
|
||||
cxx-flags: ''
|
||||
os: windows-latest
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Create build directories
|
||||
run: |
|
||||
mkdir _install
|
||||
mkdir _build
|
||||
shell: bash
|
||||
- name: Configure
|
||||
# the windows build needs the -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS to work
|
||||
run: |
|
||||
cmake ../. \
|
||||
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/_install \
|
||||
-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS='ON'\
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
-DCMAKE_CXX_STANDARD=${{ matrix.cxx-standard }} \
|
||||
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
|
||||
shell: bash
|
||||
working-directory: _build
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build . \
|
||||
--config ${{ matrix.build-type }}
|
||||
shell: bash
|
||||
working-directory: _build
|
||||
- name: Test
|
||||
run: |
|
||||
ctest -C ${{ matrix.build-type }}
|
||||
shell: bash
|
||||
working-directory: _build
|
||||
@@ -0,0 +1,145 @@
|
||||
name: Meson
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
meson-build-and-tests:
|
||||
runs-on: ${{ matrix.platform }}
|
||||
name: ${{ matrix.platform }}, ${{ matrix.mode.name }} ${{ matrix.flavor }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor:
|
||||
- debug
|
||||
- release
|
||||
mode:
|
||||
- name: default
|
||||
extra_envs: {}
|
||||
|
||||
# Alternative compiler setups
|
||||
- name: gcc
|
||||
extra_envs:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
- name: clang
|
||||
extra_envs:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
|
||||
- name: sanitize
|
||||
args: >-
|
||||
"-Db_sanitize=address,undefined"
|
||||
extra_envs: {}
|
||||
|
||||
# This is for MSVC, which only supports AddressSanitizer.
|
||||
# https://learn.microsoft.com/en-us/cpp/sanitizers/
|
||||
- name: sanitize+asanonly
|
||||
args: -Db_sanitize=address
|
||||
extra_envs:
|
||||
ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1
|
||||
|
||||
- name: clang+sanitize
|
||||
args: >-
|
||||
-Db_lundef=false "-Db_sanitize=address,undefined"
|
||||
extra_envs:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
|
||||
# default clang on GitHub hosted runners is from MSYS2.
|
||||
# Use Visual Studio supplied clang-cl instead.
|
||||
- name: clang-cl+sanitize
|
||||
args: >-
|
||||
"-Db_sanitize=address,undefined"
|
||||
extra_envs:
|
||||
CC: clang-cl
|
||||
CXX: clang-cl
|
||||
platform:
|
||||
- ubuntu-22.04
|
||||
- windows-2022
|
||||
- macos-latest
|
||||
|
||||
exclude:
|
||||
# clang-cl only makes sense on windows.
|
||||
- platform: ubuntu-22.04
|
||||
mode:
|
||||
name: clang-cl+sanitize
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: clang-cl+sanitize
|
||||
|
||||
# Use clang-cl instead of MSYS2 clang.
|
||||
#
|
||||
# we already tested clang+sanitize on linux,
|
||||
# if this doesn't work, it should be an issue for MSYS2 team to consider.
|
||||
- platform: windows-2022
|
||||
mode:
|
||||
name: clang
|
||||
- platform: windows-2022
|
||||
mode:
|
||||
name: clang+sanitize
|
||||
|
||||
# MSVC-only sanitizers
|
||||
- platform: ubuntu-22.04
|
||||
mode:
|
||||
name: sanitize+asanonly
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: sanitize+asanonly
|
||||
- platform: windows-2022
|
||||
mode:
|
||||
name: sanitize
|
||||
|
||||
# clang is the default on macos
|
||||
# also gcc is an alias to clang
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: clang
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: gcc
|
||||
|
||||
# gcc is the default on linux
|
||||
- platform: ubuntu-22.04
|
||||
mode:
|
||||
name: gcc
|
||||
|
||||
# only run sanitizer tests on linux
|
||||
#
|
||||
# gcc/clang's codegen shouldn't massively change across platforms,
|
||||
# and linux supports most of the sanitizers.
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: clang+sanitize
|
||||
- platform: macos-latest
|
||||
mode:
|
||||
name: sanitize
|
||||
steps:
|
||||
- name: Setup meson
|
||||
run: |
|
||||
pipx install meson ninja
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Activate MSVC and Configure
|
||||
if: ${{ matrix.platform == 'windows-2022' }}
|
||||
env: ${{ matrix.mode.extra_envs }}
|
||||
run: |
|
||||
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Ddefault_library=static ${{ matrix.mode.args }} --vsenv
|
||||
- name: Configuring
|
||||
if: ${{ matrix.platform != 'windows-2022' }}
|
||||
env: ${{ matrix.mode.extra_envs }}
|
||||
run: |
|
||||
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }}
|
||||
- name: Building
|
||||
run: |
|
||||
meson compile -C build-${{ matrix.flavor }}
|
||||
- name: Running tests
|
||||
env: ${{ matrix.mode.extra_envs }}
|
||||
run: |
|
||||
meson test -C build-${{ matrix.flavor }} --timeout-multiplier 0
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs
|
||||
path: build-${{ matrix.flavor }}/meson-logs
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(pystring LANGUAGES CXX VERSION 1.2.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
option (BUILD_SHARED_LIBS "Build shared libraries (set to OFF to build static libs)" ON)
|
||||
|
||||
# If the user hasn't configured cmake with an explicit
|
||||
# -DCMAKE_INSTALL_PREFIX=..., then set it to safely install into ./dist, to
|
||||
# help prevent the user from accidentally writing over /usr/local or whatever.
|
||||
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
|
||||
AND PROJECT_IS_TOP_LEVEL)
|
||||
set (CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/dist" CACHE PATH
|
||||
"Installation location" FORCE)
|
||||
endif()
|
||||
message (STATUS "Installation path will be ${CMAKE_INSTALL_PREFIX}")
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# --- Compiled library target: pystring::pystring ---
|
||||
add_library(pystring
|
||||
pystring.cpp
|
||||
pystring.h
|
||||
)
|
||||
|
||||
set_target_properties(pystring PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
)
|
||||
|
||||
target_include_directories(pystring PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(TARGETS pystring
|
||||
EXPORT pystringTargets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
|
||||
# --- Header-only target: pystring::pystring_header_only ---
|
||||
add_library(pystring_header_only INTERFACE)
|
||||
|
||||
target_compile_definitions(pystring_header_only INTERFACE PYSTRING_HEADER_ONLY)
|
||||
|
||||
target_include_directories(pystring_header_only INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(TARGETS pystring_header_only
|
||||
EXPORT pystringTargets
|
||||
)
|
||||
|
||||
install(FILES pystring.h pystring_impl.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
# --- Export & package config ---
|
||||
install(EXPORT pystringTargets
|
||||
FILE pystringTargets.cmake
|
||||
NAMESPACE pystring::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
cmake/pystringConfig.cmake.in
|
||||
pystringConfig.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
pystringConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pystringConfig.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pystringConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
|
||||
)
|
||||
|
||||
# --- Tests ---
|
||||
add_executable(pystring_test test.cpp)
|
||||
target_link_libraries(pystring_test pystring)
|
||||
|
||||
add_executable(pystring_test_header_only test.cpp)
|
||||
target_link_libraries(pystring_test_header_only pystring_header_only)
|
||||
|
||||
# Compile-time check that PYSTRING_HEADER_ONLY propagates correctly
|
||||
add_executable(pystring_test_header_only_define test_header_only_define.cpp)
|
||||
target_link_libraries(pystring_test_header_only_define pystring_header_only)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME PyStringTest COMMAND pystring_test)
|
||||
add_test(NAME PyStringTestHeaderOnly COMMAND pystring_test_header_only)
|
||||
@@ -1,30 +1,27 @@
|
||||
Copyright (c) 2008-2010, Sony Pictures Imageworks Inc
|
||||
All rights reserved.
|
||||
Copyright (c) 2008-present Contributors to the Pystring project.
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
Neither the name of the organization Sony Pictures Imageworks nor the
|
||||
names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
LIBTOOL = libtool
|
||||
LIBDIR = /usr/lib
|
||||
CXX = g++
|
||||
CXXFLAGS = -g -O3 -Wall -Wextra -Wshadow -Wconversion -Wcast-qual -Wformat=2
|
||||
LIBTOOL ?= libtool
|
||||
PREFIX ?= /usr
|
||||
INCLUDEDIR ?= ${PREFIX}/include/pystring
|
||||
LIBDIR ?= ${PREFIX}/lib
|
||||
CXX ?= g++
|
||||
CXXFLAGS ?= -g -O3 -Wall -Wextra -Wshadow -Wconversion -Wcast-qual -Wformat=2
|
||||
|
||||
all: libpystring.la
|
||||
|
||||
@@ -12,7 +14,8 @@ libpystring.la: pystring.lo
|
||||
$(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $< -rpath $(LIBDIR)
|
||||
|
||||
install: libpystring.la
|
||||
$(LIBTOOL) --mode=install install -c $< $(LIBDIR)/$<
|
||||
$(LIBTOOL) --mode=install install -Dm755 $< $(DESTDIR)$(LIBDIR)/$<
|
||||
$(LIBTOOL) --mode=install install -Dm644 pystring.h $(DESTDIR)$(INCLUDEDIR)/pystring.h
|
||||
|
||||
clean:
|
||||
$(RM) -fr pystring.lo pystring.o libpystring.la .libs
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
Pystring is a collection of C++ functions which match the interface and behavior of python's string class methods using std::string. Implemented in C++, it does not require or make use of a python interpreter. It provides convenience and familiarity for common string operations not included in the standard C++ library. It's also useful in environments where both C++ and python are used.
|
||||
|
||||
Overlapping functionality (such as index and slice/substr) of std::string is included to match python interfaces.
|
||||
|
||||
Originally developed at Sony Pictures Imageworks.
|
||||
http://opensource.imageworks.com/
|
||||
|
||||
Note: Despite the infrequent updates, this repo is not dead/abandoned - just stable! We use it every day at Imageworks.
|
||||
@@ -0,0 +1,17 @@
|
||||
[](https://repology.org/project/pystring/versions)
|
||||
|
||||
Pystring is a collection of C++ functions which match the interface and
|
||||
behavior of python's string class methods using std::string. Implemented in
|
||||
C++, it does not require or make use of a python interpreter. It provides
|
||||
convenience and familiarity for common string operations not included in the
|
||||
standard C++ library. It's also useful in environments where both C++ and
|
||||
python are used.
|
||||
|
||||
Overlapping functionality (such as index and slice/substr) of std::string is
|
||||
included to match python interfaces.
|
||||
|
||||
Originally developed at Sony Pictures Imageworks.
|
||||
http://opensource.imageworks.com/
|
||||
|
||||
Note: Despite the infrequent updates, this repo is not dead/abandoned - just
|
||||
stable! We use it every day at Imageworks.
|
||||
@@ -0,0 +1,8 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
# Prevent double-definition errors
|
||||
if(NOT TARGET pystring::pystring AND NOT TARGET pystring::pystring_header_only)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pystringTargets.cmake")
|
||||
endif()
|
||||
|
||||
check_required_components(pystring)
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
project(
|
||||
'pystring',
|
||||
'cpp',
|
||||
version: '1.2.0',
|
||||
license: 'BSD-3-Clause',
|
||||
license_files: 'LICENSE',
|
||||
meson_version: '>=1.3',
|
||||
default_options: ['cpp_std=c++17,c++11', 'warning_level=3'],
|
||||
)
|
||||
|
||||
inc = include_directories('.')
|
||||
hdrs = files('pystring.h')
|
||||
|
||||
# --- Compiled library target ---
|
||||
pystring_lib = library(
|
||||
'pystring',
|
||||
files('pystring.cpp'),
|
||||
implicit_include_directories: false,
|
||||
include_directories: inc,
|
||||
version: meson.project_version(),
|
||||
install: true,
|
||||
)
|
||||
|
||||
pystring_dep = declare_dependency(
|
||||
link_with: pystring_lib,
|
||||
include_directories: inc,
|
||||
)
|
||||
|
||||
install_headers(hdrs, subdir: 'pystring')
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
pkgconfig.generate(
|
||||
pystring_lib,
|
||||
description: 'C++ functions matching the interface and behavior of python string methods with std::string',
|
||||
)
|
||||
|
||||
# --- Header-only target ---
|
||||
pystring_header_only_dep = declare_dependency(
|
||||
include_directories: inc,
|
||||
compile_args: ['-DPYSTRING_HEADER_ONLY'],
|
||||
)
|
||||
|
||||
install_headers(hdrs, files('pystring_impl.h'), subdir: 'pystring')
|
||||
|
||||
# --- Override default dependency ---
|
||||
meson.override_dependency('pystring', pystring_dep)
|
||||
|
||||
# --- Tests ---
|
||||
test(
|
||||
'PyStringTest',
|
||||
executable(
|
||||
'pystring_test',
|
||||
'test.cpp',
|
||||
dependencies: pystring_dep,
|
||||
build_by_default: false,
|
||||
),
|
||||
)
|
||||
|
||||
test(
|
||||
'PyStringTestHeaderOnly',
|
||||
executable(
|
||||
'pystring_test_header_only',
|
||||
'test.cpp',
|
||||
dependencies: pystring_header_only_dep,
|
||||
build_by_default: false,
|
||||
),
|
||||
)
|
||||
|
||||
# Compile-time check that PYSTRING_HEADER_ONLY propagates correctly
|
||||
executable(
|
||||
'pystring_test_header_only_define',
|
||||
'test_header_only_define.cpp',
|
||||
dependencies: pystring_header_only_dep,
|
||||
build_by_default: true,
|
||||
)
|
||||
+7
-1648
File diff suppressed because it is too large
Load Diff
+123
-99
@@ -1,39 +1,17 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2008-2010, Sony Pictures Imageworks Inc
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// Neither the name of the organization Sony Pictures Imageworks nor the
|
||||
// names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS
|
||||
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER
|
||||
// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Contributors to the Pystring project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/imageworks/pystring/blob/master/LICENSE
|
||||
|
||||
|
||||
#ifndef INCLUDED_PYSTRING_H
|
||||
#define INCLUDED_PYSTRING_H
|
||||
|
||||
#ifdef PYSTRING_HEADER_ONLY
|
||||
#define PYSTRING_INLINE inline
|
||||
#else
|
||||
#define PYSTRING_INLINE
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -60,102 +38,102 @@ namespace pystring
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with only its first character capitalized.
|
||||
///
|
||||
std::string capitalize( const std::string & str );
|
||||
PYSTRING_INLINE std::string capitalize( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return centered in a string of length width. Padding is done using spaces.
|
||||
///
|
||||
std::string center( const std::string & str, int width );
|
||||
PYSTRING_INLINE std::string center( const std::string & str, int width );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the number of occurrences of substring sub in string S[start:end]. Optional
|
||||
/// arguments start and end are interpreted as in slice notation.
|
||||
///
|
||||
int count( const std::string & str, const std::string & substr, int start = 0, int end = MAX_32BIT_INT);
|
||||
PYSTRING_INLINE int count( const std::string & str, const std::string & substr, int start = 0, int end = MAX_32BIT_INT);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return True if the string ends with the specified suffix, otherwise return False. With
|
||||
/// optional start, test beginning at that position. With optional end, stop comparing at that position.
|
||||
///
|
||||
bool endswith( const std::string & str, const std::string & suffix, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE bool endswith( const std::string & str, const std::string & suffix, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string where all tab characters are expanded using spaces. If tabsize
|
||||
/// is not given, a tab size of 8 characters is assumed.
|
||||
///
|
||||
std::string expandtabs( const std::string & str, int tabsize = 8);
|
||||
PYSTRING_INLINE std::string expandtabs( const std::string & str, int tabsize = 8);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the lowest index in the string where substring sub is found, such that sub is
|
||||
/// contained in the range [start, end). Optional arguments start and end are interpreted as
|
||||
/// in slice notation. Return -1 if sub is not found.
|
||||
///
|
||||
int find( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE int find( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Synonym of find right now. Python version throws exceptions. This one currently doesn't
|
||||
///
|
||||
int index( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE int index( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if all characters in the string are alphanumeric and there is at least one
|
||||
/// character, false otherwise.
|
||||
///
|
||||
bool isalnum( const std::string & str );
|
||||
PYSTRING_INLINE bool isalnum( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if all characters in the string are alphabetic and there is at least one
|
||||
/// character, false otherwise
|
||||
///
|
||||
bool isalpha( const std::string & str );
|
||||
PYSTRING_INLINE bool isalpha( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if all characters in the string are digits and there is at least one
|
||||
/// character, false otherwise.
|
||||
///
|
||||
bool isdigit( const std::string & str );
|
||||
PYSTRING_INLINE bool isdigit( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if all cased characters in the string are lowercase and there is at least one
|
||||
/// cased character, false otherwise.
|
||||
///
|
||||
bool islower( const std::string & str );
|
||||
PYSTRING_INLINE bool islower( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if there are only whitespace characters in the string and there is at least
|
||||
/// one character, false otherwise.
|
||||
///
|
||||
bool isspace( const std::string & str );
|
||||
PYSTRING_INLINE bool isspace( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if the string is a titlecased string and there is at least one character,
|
||||
/// i.e. uppercase characters may only follow uncased characters and lowercase characters only
|
||||
/// cased ones. Return false otherwise.
|
||||
///
|
||||
bool istitle( const std::string & str );
|
||||
PYSTRING_INLINE bool istitle( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return true if all cased characters in the string are uppercase and there is at least one
|
||||
/// cased character, false otherwise.
|
||||
///
|
||||
bool isupper( const std::string & str );
|
||||
PYSTRING_INLINE bool isupper( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a string which is the concatenation of the strings in the sequence seq.
|
||||
/// The separator between elements is the str argument
|
||||
///
|
||||
std::string join( const std::string & str, const std::vector< std::string > & seq );
|
||||
PYSTRING_INLINE std::string join( const std::string & str, const std::vector< std::string > & seq );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the string left justified in a string of length width. Padding is done using
|
||||
/// spaces. The original string is returned if width is less than str.size().
|
||||
///
|
||||
std::string ljust( const std::string & str, int width );
|
||||
PYSTRING_INLINE std::string ljust( const std::string & str, int width );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string converted to lowercase.
|
||||
///
|
||||
std::string lower( const std::string & str );
|
||||
PYSTRING_INLINE std::string lower( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with leading characters removed. If chars is omitted or None,
|
||||
@@ -163,13 +141,13 @@ namespace pystring
|
||||
/// characters in the string will be stripped from the beginning of the string this method
|
||||
/// is called on (argument "str" ).
|
||||
///
|
||||
std::string lstrip( const std::string & str, const std::string & chars = "" );
|
||||
PYSTRING_INLINE std::string lstrip( const std::string & str, const std::string & chars = "" );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string, concatenated N times, together.
|
||||
/// Corresponds to the __mul__ operator.
|
||||
///
|
||||
std::string mul( const std::string & str, int n);
|
||||
PYSTRING_INLINE std::string mul( const std::string & str, int n);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Split the string around first occurance of sep.
|
||||
@@ -177,32 +155,50 @@ namespace pystring
|
||||
/// be the text before sep, sep itself, and the remaining text. If sep is
|
||||
/// not found, the original string will be returned with two empty strings.
|
||||
///
|
||||
void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result );
|
||||
PYSTRING_INLINE void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result );
|
||||
inline std::vector< std::string > partition( const std::string & str, const std::string & sep )
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
partition( str, sep, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief If str starts with prefix return a copy of the string with prefix at the start
|
||||
/// removed otherwise return an unmodified copy of the string.
|
||||
///
|
||||
PYSTRING_INLINE std::string removeprefix( const std::string & str, const std::string & prefix );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief If str ends with suffix return a copy of the string with suffix at the end removed
|
||||
/// otherwise return an unmodified copy of the string.
|
||||
///
|
||||
PYSTRING_INLINE std::string removesuffix( const std::string & str, const std::string & suffix );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with all occurrences of substring old replaced by new. If
|
||||
/// the optional argument count is given, only the first count occurrences are replaced.
|
||||
///
|
||||
std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count = -1);
|
||||
PYSTRING_INLINE std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count = -1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the highest index in the string where substring sub is found, such that sub is
|
||||
/// contained within s[start,end]. Optional arguments start and end are interpreted as in
|
||||
/// slice notation. Return -1 on failure.
|
||||
///
|
||||
int rfind( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE int rfind( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Currently a synonym of rfind. The python version raises exceptions. This one currently
|
||||
/// does not
|
||||
///
|
||||
int rindex( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE int rindex( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the string right justified in a string of length width. Padding is done using
|
||||
/// spaces. The original string is returned if width is less than str.size().
|
||||
///
|
||||
std::string rjust( const std::string & str, int width);
|
||||
PYSTRING_INLINE std::string rjust( const std::string & str, int width);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Split the string around last occurance of sep.
|
||||
@@ -210,21 +206,33 @@ namespace pystring
|
||||
/// be the text before sep, sep itself, and the remaining text. If sep is
|
||||
/// not found, the original string will be returned with two empty strings.
|
||||
///
|
||||
void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result );
|
||||
PYSTRING_INLINE void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result );
|
||||
inline std::vector< std::string > rpartition ( const std::string & str, const std::string & sep )
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
rpartition( str, sep, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with trailing characters removed. If chars is "", whitespace
|
||||
/// characters are removed. If not "", the characters in the string will be stripped from the
|
||||
/// end of the string this method is called on.
|
||||
///
|
||||
std::string rstrip( const std::string & str, const std::string & chars = "" );
|
||||
PYSTRING_INLINE std::string rstrip( const std::string & str, const std::string & chars = "" );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Fills the "result" list with the words in the string, using sep as the delimiter string.
|
||||
/// If maxsplit is > -1, at most maxsplit splits are done. If sep is "",
|
||||
/// any whitespace string is a separator.
|
||||
///
|
||||
void split( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1);
|
||||
PYSTRING_INLINE void split( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1);
|
||||
inline std::vector< std::string > split( const std::string & str, const std::string & sep = "", int maxsplit = -1)
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
split( str, result, sep, maxsplit );
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Fills the "result" list with the words in the string, using sep as the delimiter string.
|
||||
@@ -233,61 +241,73 @@ namespace pystring
|
||||
/// If maxsplit is > -1, at most maxsplit splits are done. If sep is "",
|
||||
/// any whitespace string is a separator.
|
||||
///
|
||||
void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1);
|
||||
PYSTRING_INLINE void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1);
|
||||
inline std::vector< std::string > rsplit( const std::string & str, const std::string & sep = "", int maxsplit = -1)
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
rsplit( str, result, sep, maxsplit);
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a list of the lines in the string, breaking at line boundaries. Line breaks
|
||||
/// are not included in the resulting list unless keepends is given and true.
|
||||
///
|
||||
void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends = false );
|
||||
PYSTRING_INLINE void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends = false );
|
||||
inline std::vector< std::string > splitlines( const std::string & str, bool keepends = false )
|
||||
{
|
||||
std::vector< std::string > result;
|
||||
splitlines( str, result, keepends);
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return True if string starts with the prefix, otherwise return False. With optional start,
|
||||
/// test string beginning at that position. With optional end, stop comparing string at that
|
||||
/// position
|
||||
///
|
||||
bool startswith( const std::string & str, const std::string & prefix, int start = 0, int end = MAX_32BIT_INT );
|
||||
PYSTRING_INLINE bool startswith( const std::string & str, const std::string & prefix, int start = 0, int end = MAX_32BIT_INT );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with leading and trailing characters removed. If chars is "",
|
||||
/// whitespace characters are removed. If given not "", the characters in the string will be
|
||||
/// stripped from the both ends of the string this method is called on.
|
||||
///
|
||||
std::string strip( const std::string & str, const std::string & chars = "" );
|
||||
PYSTRING_INLINE std::string strip( const std::string & str, const std::string & chars = "" );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string with uppercase characters converted to lowercase and vice versa.
|
||||
///
|
||||
std::string swapcase( const std::string & str );
|
||||
PYSTRING_INLINE std::string swapcase( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a titlecased version of the string: words start with uppercase characters,
|
||||
/// all remaining cased characters are lowercase.
|
||||
///
|
||||
std::string title( const std::string & str );
|
||||
PYSTRING_INLINE std::string title( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string where all characters occurring in the optional argument
|
||||
/// deletechars are removed, and the remaining characters have been mapped through the given
|
||||
/// translation table, which must be a string of length 256.
|
||||
///
|
||||
std::string translate( const std::string & str, const std::string & table, const std::string & deletechars = "");
|
||||
PYSTRING_INLINE std::string translate( const std::string & str, const std::string & table, const std::string & deletechars = "");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a copy of the string converted to uppercase.
|
||||
///
|
||||
std::string upper( const std::string & str );
|
||||
PYSTRING_INLINE std::string upper( const std::string & str );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the numeric string left filled with zeros in a string of length width. The original
|
||||
/// string is returned if width is less than str.size().
|
||||
///
|
||||
std::string zfill( const std::string & str, int width );
|
||||
PYSTRING_INLINE std::string zfill( const std::string & str, int width );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief function matching python's slice functionality.
|
||||
///
|
||||
std::string slice( const std::string & str, int start = 0, int end = MAX_32BIT_INT);
|
||||
PYSTRING_INLINE std::string slice( const std::string & str, int start = 0, int end = MAX_32BIT_INT);
|
||||
|
||||
///
|
||||
/// @ }
|
||||
@@ -325,26 +345,26 @@ namespace path
|
||||
/// program; where basename for '/foo/bar/' returns 'bar', the basename() function returns an
|
||||
/// empty string ('').
|
||||
|
||||
std::string basename(const std::string & path);
|
||||
std::string basename_nt(const std::string & path);
|
||||
std::string basename_posix(const std::string & path);
|
||||
PYSTRING_INLINE std::string basename(const std::string & path);
|
||||
PYSTRING_INLINE std::string basename_nt(const std::string & path);
|
||||
PYSTRING_INLINE std::string basename_posix(const std::string & path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return the directory name of pathname path. This is the first half of the pair
|
||||
/// returned by split(path).
|
||||
|
||||
std::string dirname(const std::string & path);
|
||||
std::string dirname_nt(const std::string & path);
|
||||
std::string dirname_posix(const std::string & path);
|
||||
PYSTRING_INLINE std::string dirname(const std::string & path);
|
||||
PYSTRING_INLINE std::string dirname_nt(const std::string & path);
|
||||
PYSTRING_INLINE std::string dirname_posix(const std::string & path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return True if path is an absolute pathname. On Unix, that means it begins with a
|
||||
/// slash, on Windows that it begins with a (back)slash after chopping off a potential drive
|
||||
/// letter.
|
||||
|
||||
bool isabs(const std::string & path);
|
||||
bool isabs_nt(const std::string & path);
|
||||
bool isabs_posix(const std::string & s);
|
||||
PYSTRING_INLINE bool isabs(const std::string & path);
|
||||
PYSTRING_INLINE bool isabs_nt(const std::string & path);
|
||||
PYSTRING_INLINE bool isabs_posix(const std::string & s);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Return a normalized absolutized version of the pathname path.
|
||||
@@ -352,9 +372,9 @@ namespace path
|
||||
/// NOTE: This differs from the interface of the python equivalent in that it requires you
|
||||
/// to pass in the current working directory as an argument.
|
||||
|
||||
std::string abspath(const std::string & path, const std::string & cwd);
|
||||
std::string abspath_nt(const std::string & path, const std::string & cwd);
|
||||
std::string abspath_posix(const std::string & path, const std::string & cwd);
|
||||
PYSTRING_INLINE std::string abspath(const std::string & path, const std::string & cwd);
|
||||
PYSTRING_INLINE std::string abspath_nt(const std::string & path, const std::string & cwd);
|
||||
PYSTRING_INLINE std::string abspath_posix(const std::string & path, const std::string & cwd);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -367,13 +387,13 @@ namespace path
|
||||
/// current directory on drive C: (c:foo), not c:\foo.
|
||||
|
||||
/// This dispatches based on the compilation OS
|
||||
std::string join(const std::string & path1, const std::string & path2);
|
||||
std::string join_nt(const std::string & path1, const std::string & path2);
|
||||
std::string join_posix(const std::string & path1, const std::string & path2);
|
||||
PYSTRING_INLINE std::string join(const std::string & path1, const std::string & path2);
|
||||
PYSTRING_INLINE std::string join_nt(const std::string & path1, const std::string & path2);
|
||||
PYSTRING_INLINE std::string join_posix(const std::string & path1, const std::string & path2);
|
||||
|
||||
std::string join(const std::vector< std::string > & paths);
|
||||
std::string join_nt(const std::vector< std::string > & paths);
|
||||
std::string join_posix(const std::vector< std::string > & paths);
|
||||
PYSTRING_INLINE std::string join(const std::vector< std::string > & paths);
|
||||
PYSTRING_INLINE std::string join_nt(const std::vector< std::string > & paths);
|
||||
PYSTRING_INLINE std::string join_posix(const std::vector< std::string > & paths);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Normalize a pathname. This collapses redundant separators and up-level references
|
||||
@@ -382,9 +402,9 @@ namespace path
|
||||
/// It should be understood that this may change the meaning of the path if it contains
|
||||
/// symbolic links!
|
||||
|
||||
std::string normpath(const std::string & path);
|
||||
std::string normpath_nt(const std::string & path);
|
||||
std::string normpath_posix(const std::string & path);
|
||||
PYSTRING_INLINE std::string normpath(const std::string & path);
|
||||
PYSTRING_INLINE std::string normpath_nt(const std::string & path);
|
||||
PYSTRING_INLINE std::string normpath_posix(const std::string & path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Split the pathname path into a pair, (head, tail) where tail is the last pathname
|
||||
@@ -395,9 +415,9 @@ namespace path
|
||||
/// join(head, tail) returns a path to the same location as path (but the strings may
|
||||
/// differ).
|
||||
|
||||
void split(std::string & head, std::string & tail, const std::string & path);
|
||||
void split_nt(std::string & head, std::string & tail, const std::string & path);
|
||||
void split_posix(std::string & head, std::string & tail, const std::string & path);
|
||||
PYSTRING_INLINE void split(std::string & head, std::string & tail, const std::string & path);
|
||||
PYSTRING_INLINE void split_nt(std::string & head, std::string & tail, const std::string & path);
|
||||
PYSTRING_INLINE void split_posix(std::string & head, std::string & tail, const std::string & path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Split the pathname path into a pair (drive, tail) where drive is either a drive
|
||||
@@ -405,18 +425,18 @@ namespace path
|
||||
/// drive will always be the empty string. In all cases, drive + tail will be the same as
|
||||
/// path.
|
||||
|
||||
void splitdrive(std::string & drivespec, std::string & pathspec, const std::string & path);
|
||||
void splitdrive_nt(std::string & drivespec, std::string & pathspec, const std::string & p);
|
||||
void splitdrive_posix(std::string & drivespec, std::string & pathspec, const std::string & path);
|
||||
PYSTRING_INLINE void splitdrive(std::string & drivespec, std::string & pathspec, const std::string & path);
|
||||
PYSTRING_INLINE void splitdrive_nt(std::string & drivespec, std::string & pathspec, const std::string & p);
|
||||
PYSTRING_INLINE void splitdrive_posix(std::string & drivespec, std::string & pathspec, const std::string & path);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Split the pathname path into a pair (root, ext) such that root + ext == path, and
|
||||
/// ext is empty or begins with a period and contains at most one period. Leading periods on
|
||||
/// the basename are ignored; splitext('.cshrc') returns ('.cshrc', '').
|
||||
|
||||
void splitext(std::string & root, std::string & ext, const std::string & path);
|
||||
void splitext_nt(std::string & root, std::string & ext, const std::string & path);
|
||||
void splitext_posix(std::string & root, std::string & ext, const std::string & path);
|
||||
PYSTRING_INLINE void splitext(std::string & root, std::string & ext, const std::string & path);
|
||||
PYSTRING_INLINE void splitext_nt(std::string & root, std::string & ext, const std::string & path);
|
||||
PYSTRING_INLINE void splitext_posix(std::string & root, std::string & ext, const std::string & path);
|
||||
|
||||
///
|
||||
/// @ }
|
||||
@@ -426,4 +446,8 @@ namespace path
|
||||
|
||||
} // namespace pystring
|
||||
|
||||
#if PYSTRING_HEADER_ONLY
|
||||
#include "pystring_impl.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+1693
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
// test_header_only_mode.cpp
|
||||
#ifndef PYSTRING_HEADER_ONLY
|
||||
#error "PYSTRING_HEADER_ONLY must be defined when using the header-only target"
|
||||
#endif
|
||||
int main() { return 0; }
|
||||
+11
-40
@@ -1,35 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2008-2010, Sony Pictures Imageworks Inc
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// Neither the name of the organization Sony Pictures Imageworks nor the
|
||||
// names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS
|
||||
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER
|
||||
// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Contributors to the Pystring project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// https://github.com/imageworks/pystring/blob/master/LICENSE
|
||||
|
||||
#ifndef INCLUDED_PYSTRING_UNITTEST_H
|
||||
#define INCLUDED_PYSTRING_UNITTEST_H
|
||||
@@ -52,11 +23,11 @@ struct PYSTRINGTest
|
||||
PYSTRINGTestFunc function;
|
||||
};
|
||||
|
||||
typedef std::vector<PYSTRINGTest*> UnitTests;
|
||||
typedef std::vector<PYSTRINGTest> UnitTests;
|
||||
|
||||
UnitTests& GetUnitTests();
|
||||
|
||||
struct AddTest { AddTest(PYSTRINGTest* test); };
|
||||
struct AddTest { AddTest(PYSTRINGTest&& test); };
|
||||
|
||||
/// PYSTRING_CHECK_* macros checks if the conditions is met, and if not,
|
||||
/// prints an error message indicating the module and line where the
|
||||
@@ -131,22 +102,22 @@ struct AddTest { AddTest(PYSTRINGTest* test); };
|
||||
|
||||
#define PYSTRING_ADD_TEST(group, name) \
|
||||
static void pystringtest_##group##_##name(); \
|
||||
AddTest pystringaddtest_##group##_##name(new PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \
|
||||
AddTest pystringaddtest_##group##_##name(PYSTRINGTest(#group, #name, pystringtest_##group##_##name)); \
|
||||
static void pystringtest_##group##_##name()
|
||||
|
||||
#define PYSTRING_TEST_SETUP() \
|
||||
int unit_test_failures = 0
|
||||
|
||||
#define PYSTRING_TEST_APP(app) \
|
||||
std::vector<PYSTRINGTest*>& GetUnitTests() { \
|
||||
static std::vector<PYSTRINGTest*> pystring_unit_tests; \
|
||||
std::vector<PYSTRINGTest>& GetUnitTests() { \
|
||||
static std::vector<PYSTRINGTest> pystring_unit_tests; \
|
||||
return pystring_unit_tests; } \
|
||||
AddTest::AddTest(PYSTRINGTest* test){GetUnitTests().push_back(test);}; \
|
||||
AddTest::AddTest(PYSTRINGTest&& test){GetUnitTests().emplace_back(test);} \
|
||||
PYSTRING_TEST_SETUP(); \
|
||||
int main(int, char **) { std::cerr << "\n" << #app <<"\n\n"; \
|
||||
for(size_t i = 0; i < GetUnitTests().size(); ++i) { \
|
||||
int _tmp = unit_test_failures; GetUnitTests()[i]->function(); \
|
||||
std::cerr << "Test [" << GetUnitTests()[i]->group << "] [" << GetUnitTests()[i]->name << "] - "; \
|
||||
int _tmp = unit_test_failures; GetUnitTests()[i].function(); \
|
||||
std::cerr << "Test [" << GetUnitTests()[i].group << "] [" << GetUnitTests()[i].name << "] - "; \
|
||||
std::cerr << (_tmp == unit_test_failures ? "PASSED" : "FAILED") << "\n"; } \
|
||||
std::cerr << "\n" << unit_test_failures << " tests failed\n\n"; \
|
||||
return unit_test_failures; }
|
||||
|
||||
Reference in New Issue
Block a user