mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +01:00
Updated version of Clara (should fix Windows compile issues)
- embedded using new embed script
This commit is contained in:
parent
ee0defb939
commit
da5964af78
84
include/external/clara.hpp
vendored
84
include/external/clara.hpp
vendored
@ -4,23 +4,40 @@
|
|||||||
#ifndef CATCH_CLARA_HPP_INCLUDED
|
#ifndef CATCH_CLARA_HPP_INCLUDED
|
||||||
#define CATCH_CLARA_HPP_INCLUDED
|
#define CATCH_CLARA_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
|
#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------- #included from clara_textflow.hpp -----------
|
||||||
|
|
||||||
|
// TextFlowCpp
|
||||||
|
//
|
||||||
|
// A single-header library for wrapping and laying out basic text, by Phil Nash
|
||||||
|
//
|
||||||
|
// This work is licensed under the BSD 2-Clause license.
|
||||||
|
// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
|
||||||
|
//
|
||||||
|
// This project is hosted at https://github.com/philsquared/textflowcpp
|
||||||
|
|
||||||
|
#ifndef CATCH_CLARA_TEXTFLOW_HPP_INCLUDED
|
||||||
|
#define CATCH_CLARA_TEXTFLOW_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
#include <set>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#ifndef CLARA_CONFIG_CONSOLE_WIDTH
|
#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
|
||||||
#define CLARA_CONFIG_CONSOLE_WIDTH 80
|
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
|
||||||
namespace clara {
|
|
||||||
|
|
||||||
// Included from TextFlow.hpp
|
namespace Catch { namespace clara { namespace TextFlow
|
||||||
namespace TextFlow {
|
{
|
||||||
|
|
||||||
inline auto isWhitespace( char c ) -> bool {
|
inline auto isWhitespace( char c ) -> bool {
|
||||||
static std::string chars = " \t\n\r";
|
static std::string chars = " \t\n\r";
|
||||||
@ -39,7 +56,7 @@ namespace TextFlow {
|
|||||||
|
|
||||||
class Column {
|
class Column {
|
||||||
std::vector<std::string> m_strings;
|
std::vector<std::string> m_strings;
|
||||||
size_t m_width = CLARA_CONFIG_CONSOLE_WIDTH;
|
size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t m_indent = 0;
|
size_t m_indent = 0;
|
||||||
size_t m_initialIndent = std::string::npos;
|
size_t m_initialIndent = std::string::npos;
|
||||||
|
|
||||||
@ -51,7 +68,7 @@ namespace TextFlow {
|
|||||||
size_t m_stringIndex = 0;
|
size_t m_stringIndex = 0;
|
||||||
size_t m_pos = 0;
|
size_t m_pos = 0;
|
||||||
|
|
||||||
size_t m_len;
|
size_t m_len = 0;
|
||||||
bool m_suffix = false;
|
bool m_suffix = false;
|
||||||
|
|
||||||
iterator( Column const& column, size_t stringIndex )
|
iterator( Column const& column, size_t stringIndex )
|
||||||
@ -171,7 +188,7 @@ namespace TextFlow {
|
|||||||
|
|
||||||
auto width() const -> size_t { return m_width; }
|
auto width() const -> size_t { return m_width; }
|
||||||
auto begin() const -> iterator { return iterator( *this ); }
|
auto begin() const -> iterator { return iterator( *this ); }
|
||||||
auto end() const -> iterator { return iterator( *this, m_strings.size() ); }
|
auto end() const -> iterator { return { *this, m_strings.size() }; }
|
||||||
|
|
||||||
inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
|
inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
@ -197,7 +214,7 @@ namespace TextFlow {
|
|||||||
class Spacer : public Column {
|
class Spacer : public Column {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Spacer( size_t spaceWidth ) : Column( "" ) {
|
explicit Spacer( size_t spaceWidth ) : Column( "" ) {
|
||||||
width( spaceWidth );
|
width( spaceWidth );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -226,7 +243,7 @@ namespace TextFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iterator( Columns const& columns )
|
explicit iterator( Columns const& columns )
|
||||||
: m_columns( columns.m_columns ),
|
: m_columns( columns.m_columns ),
|
||||||
m_activeIterators( m_columns.size() )
|
m_activeIterators( m_columns.size() )
|
||||||
{
|
{
|
||||||
@ -277,7 +294,7 @@ namespace TextFlow {
|
|||||||
using const_iterator = iterator;
|
using const_iterator = iterator;
|
||||||
|
|
||||||
auto begin() const -> iterator { return iterator( *this ); }
|
auto begin() const -> iterator { return iterator( *this ); }
|
||||||
auto end() const -> iterator { return iterator( *this, iterator::EndTag() ); }
|
auto end() const -> iterator { return { *this, iterator::EndTag() }; }
|
||||||
|
|
||||||
auto operator += ( Column const& col ) -> Columns& {
|
auto operator += ( Column const& col ) -> Columns& {
|
||||||
m_columns.push_back( col );
|
m_columns.push_back( col );
|
||||||
@ -315,9 +332,19 @@ namespace TextFlow {
|
|||||||
cols += other;
|
cols += other;
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
}}} // namespace Catch::clara::TextFlow
|
||||||
|
|
||||||
} // namespace TextFlow
|
#endif // CATCH_CLARA_TEXTFLOW_HPP_INCLUDED
|
||||||
|
|
||||||
|
// ----------- end of #include from clara_textflow.hpp -----------
|
||||||
|
// ........... back in clara.hpp
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Catch { namespace clara {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// Traits for extracting arg and return type of lambdas (for single argument lambdas)
|
// Traits for extracting arg and return type of lambdas (for single argument lambdas)
|
||||||
@ -475,8 +502,7 @@ namespace detail {
|
|||||||
new(&m_value) T(other.m_value);
|
new(&m_value) T(other.m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultValueBase(Type type, T const &value)
|
ResultValueBase(Type, T const &value) : ResultBase(Ok) {
|
||||||
: ResultBase(Ok) {
|
|
||||||
new(&m_value) T(value);
|
new(&m_value) T(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,10 +626,9 @@ namespace detail {
|
|||||||
target = source;
|
target = source;
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
return ParserResult::ok(ParseResultType::Matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
|
inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
|
||||||
std::string srcLC = source;
|
std::string srcLC = source;
|
||||||
std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), ::tolower);
|
std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](char c) { return static_cast<char>( ::tolower(c) ); } );
|
||||||
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
|
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
|
||||||
target = true;
|
target = true;
|
||||||
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
|
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
|
||||||
@ -869,7 +894,7 @@ namespace detail {
|
|||||||
public:
|
public:
|
||||||
using ParserRefImpl::ParserRefImpl;
|
using ParserRefImpl::ParserRefImpl;
|
||||||
|
|
||||||
auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
|
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
|
||||||
auto validationResult = validate();
|
auto validationResult = validate();
|
||||||
if (!validationResult)
|
if (!validationResult)
|
||||||
return InternalParseResult(validationResult);
|
return InternalParseResult(validationResult);
|
||||||
@ -941,10 +966,10 @@ namespace detail {
|
|||||||
|
|
||||||
using ParserBase::parse;
|
using ParserBase::parse;
|
||||||
|
|
||||||
auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
|
auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
|
||||||
auto result = validate();
|
auto validationResult = validate();
|
||||||
if (!result)
|
if (!validationResult)
|
||||||
return InternalParseResult(result);
|
return InternalParseResult(validationResult);
|
||||||
|
|
||||||
auto remainingTokens = tokens;
|
auto remainingTokens = tokens;
|
||||||
if (remainingTokens && remainingTokens->type == TokenType::Option) {
|
if (remainingTokens && remainingTokens->type == TokenType::Option) {
|
||||||
@ -1069,6 +1094,7 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto rows = getHelpColumns();
|
auto rows = getHelpColumns();
|
||||||
|
size_t consoleWidth = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t optWidth = 0;
|
size_t optWidth = 0;
|
||||||
for (auto const &cols : rows)
|
for (auto const &cols : rows)
|
||||||
optWidth = std::max(optWidth, cols.left.size() + 2);
|
optWidth = std::max(optWidth, cols.left.size() + 2);
|
||||||
@ -1077,7 +1103,7 @@ namespace detail {
|
|||||||
auto row =
|
auto row =
|
||||||
TextFlow::Column(cols.left).width(optWidth).indent(2) +
|
TextFlow::Column(cols.left).width(optWidth).indent(2) +
|
||||||
TextFlow::Spacer(4) +
|
TextFlow::Spacer(4) +
|
||||||
TextFlow::Column(cols.right).width(73 - optWidth);
|
TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
|
||||||
os << row << std::endl;
|
os << row << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1131,7 +1157,7 @@ namespace detail {
|
|||||||
|
|
||||||
auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
|
auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
|
||||||
while (result.value().remainingTokens()) {
|
while (result.value().remainingTokens()) {
|
||||||
int remainingTokenCount = result.value().remainingTokens().count();
|
auto remainingTokenCount = result.value().remainingTokens().count();
|
||||||
for (auto parser : allParsers) {
|
for (auto parser : allParsers) {
|
||||||
result = parser->parse( exeName, result.value().remainingTokens() );
|
result = parser->parse( exeName, result.value().remainingTokens() );
|
||||||
if (!result || result.value().type() != ParseResultType::NoMatch) {
|
if (!result || result.value().type() != ParseResultType::NoMatch) {
|
||||||
@ -1183,7 +1209,7 @@ using detail::ParseResultType;
|
|||||||
using detail::ParserResult;
|
using detail::ParserResult;
|
||||||
|
|
||||||
|
|
||||||
} // namespace clara
|
}} // namespace Catch::clara
|
||||||
} // namespace Catch
|
|
||||||
|
|
||||||
#endif // CATCH_CLARA_HPP_INCLUDED
|
#endif // CATCH_CLARA_HPP_INCLUDED
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
|
|
||||||
// Use Catch's value for console width (store Clara's off to the side, if present)
|
// Use Catch's value for console width (store Clara's off to the side, if present)
|
||||||
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
|
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
|
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
|
||||||
#undef CLARA_CONFIG_CONSOLE_WIDTH
|
#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
|
||||||
#endif
|
#endif
|
||||||
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
|
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
|
||||||
|
|
||||||
|
|
||||||
#include "../external/clara.hpp"
|
#include "../external/clara.hpp"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
// Restore Clara's value for console width, if present
|
// Restore Clara's value for console width, if present
|
||||||
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
73
scripts/embed.py
Normal file
73
scripts/embed.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
preprocessorRe = re.compile( r'\s*#.*' )
|
||||||
|
|
||||||
|
fdefineRe = re.compile( r'\s*#\s*define\s*(\S*)\s*\(' ) # #defines that take arguments
|
||||||
|
defineRe = re.compile( r'\s*#\s*define\s*(\S*)(\s+)(.*)' ) # all #defines
|
||||||
|
undefRe = re.compile( r'\s*#\s*undef\s*(\S*)' ) # all #undefs
|
||||||
|
|
||||||
|
ifdefCommonRe = re.compile( r'\s*#\s*if' ) # all #ifdefs
|
||||||
|
ifdefRe = re.compile( r'\s*#\s*ifdef\s*(\S*)' )
|
||||||
|
ifndefRe = re.compile( r'\s*#\s*ifndef\s*(\S*)' )
|
||||||
|
endifRe = re.compile( r'\s*#\s*endif\s*//\s*(.*)' )
|
||||||
|
elseRe = re.compile( r'\s*#\s*else' )
|
||||||
|
ifRe = re.compile( r'\s*#\s*if\s+(.*)' )
|
||||||
|
|
||||||
|
nsRe = re.compile( r'(.*?\s*\s*namespace\s+)(\w+)(\s*{?)(.*)' )
|
||||||
|
nsCloseRe = re.compile( r'(.*\s*})(\s*\/\/\s*namespace\s+)(\w+)(\s*)(.*)' )
|
||||||
|
|
||||||
|
|
||||||
|
class LineMapper:
|
||||||
|
def __init__( self, idMap, outerNamespace ):
|
||||||
|
self.idMap = idMap
|
||||||
|
self.outerNamespace = outerNamespace
|
||||||
|
|
||||||
|
def replaceId( self, lineNo, id ):
|
||||||
|
if not self.idMap.has_key( id ):
|
||||||
|
raise ValueError( "Unrecognised macro identifier: '{0}' on line: {1}".format( id, lineNo ) )
|
||||||
|
subst = self.idMap[id]
|
||||||
|
if subst == "":
|
||||||
|
return id
|
||||||
|
else:
|
||||||
|
return subst
|
||||||
|
|
||||||
|
# TBD:
|
||||||
|
# #if, #ifdef, comments after #else
|
||||||
|
def mapLine( self, lineNo, line ):
|
||||||
|
m = ifndefRe.match( line )
|
||||||
|
if m:
|
||||||
|
return "#ifndef " + self.replaceId( lineNo, m.group(1)) + "\n"
|
||||||
|
m = defineRe.match( line )
|
||||||
|
if m:
|
||||||
|
return "#define {0}{1}{2}\n".format( self.replaceId( lineNo, m.group(1)), m.group(2), m.group(3) )
|
||||||
|
m = endifRe.match( line )
|
||||||
|
if m:
|
||||||
|
return "#endif // " + self.replaceId( lineNo, m.group(1)) + "\n"
|
||||||
|
m = nsCloseRe.match( line )
|
||||||
|
if m:
|
||||||
|
originalNs = m.group(3)
|
||||||
|
# print("[{0}] originalNs: '{1}' - closing".format(lineNo, originalNs))
|
||||||
|
# print( " " + line )
|
||||||
|
# print( " 1:[{0}]\n 2:[{1}]\n 3:[{2}]\n 4:[{3}]\n 5:[{4}]".format( m.group(1), m.group(2), m.group(3), m.group(4), m.group(5) ) )
|
||||||
|
if self.outerNamespace.has_key(originalNs):
|
||||||
|
outerNs, innerNs = self.outerNamespace[originalNs]
|
||||||
|
return "{0}}}{1}{2}::{3}{4}{5}\n".format( m.group(1), m.group(2), outerNs, innerNs, m.group(4), m.group(5))
|
||||||
|
m = nsRe.match( line )
|
||||||
|
if m:
|
||||||
|
originalNs = m.group(2)
|
||||||
|
# print("[{0}] originalNs: '{1}'".format(lineNo, originalNs))
|
||||||
|
# print( " " + line )
|
||||||
|
# print( " 1:[{0}]\n 2:[{1}]\n 3:[{2}]\n 4:[{3}]".format( m.group(1), m.group(2), m.group(3), m.group(4) ) )
|
||||||
|
if self.outerNamespace.has_key(originalNs):
|
||||||
|
outerNs, innerNs = self.outerNamespace[originalNs]
|
||||||
|
return "{0}{1} {{ namespace {2}{3}{4}\n".format( m.group(1), outerNs, innerNs, m.group(3), m.group(4) )
|
||||||
|
return line
|
||||||
|
|
||||||
|
def mapFile(self, filenameIn, filenameOut ):
|
||||||
|
print( "Embedding:\n {0}\nas:\n {1}".format( filenameIn, filenameOut ) )
|
||||||
|
with open( filenameIn, 'r' ) as f, open( filenameOut, 'w' ) as outf:
|
||||||
|
lineNo = 1
|
||||||
|
for line in f:
|
||||||
|
outf.write( self.mapLine( lineNo, line ) )
|
||||||
|
lineNo = lineNo + 1
|
||||||
|
print( "Written {0} lines".format( lineNo ) )
|
24
scripts/embedClara.py
Normal file
24
scripts/embedClara.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Execute this script any time you import a new copy of Clara into the third_party area
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import embed
|
||||||
|
|
||||||
|
rootPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0])))
|
||||||
|
|
||||||
|
filename = os.path.join( rootPath, "third_party", "clara.hpp" )
|
||||||
|
outfilename = os.path.join( rootPath, "include", "external", "clara.hpp" )
|
||||||
|
|
||||||
|
|
||||||
|
# Mapping of pre-processor identifiers
|
||||||
|
idMap = {
|
||||||
|
"CLARA_HPP_INCLUDED": "CATCH_CLARA_HPP_INCLUDED",
|
||||||
|
"CLARA_CONFIG_CONSOLE_WIDTH": "CATCH_CLARA_CONFIG_CONSOLE_WIDTH",
|
||||||
|
"CLARA_TEXTFLOW_HPP_INCLUDED": "CATCH_CLARA_TEXTFLOW_HPP_INCLUDED",
|
||||||
|
"CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH": "CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH"
|
||||||
|
}
|
||||||
|
|
||||||
|
# outer namespace to add
|
||||||
|
outerNamespace = { "clara": ("Catch", "clara") }
|
||||||
|
|
||||||
|
mapper = embed.LineMapper( idMap, outerNamespace )
|
||||||
|
mapper.mapFile( filename, outfilename )
|
1211
third_party/clara.hpp
vendored
Normal file
1211
third_party/clara.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user