diff options
| author | Szczepan Zalega <szczepan@nitrokey.com> | 2017-12-22 16:53:56 +0100 | 
|---|---|---|
| committer | Szczepan Zalega <szczepan@nitrokey.com> | 2017-12-22 16:53:56 +0100 | 
| commit | 48b3d82ffe1ed19db9ba3cf7e6536ecf92e27391 (patch) | |
| tree | 83645ddf58fd9514e1fe6d566839bb2747ee4706 /include/external/tbc_text_format.h | |
| download | libnitrokey-48b3d82ffe1ed19db9ba3cf7e6536ecf92e27391.tar.gz libnitrokey-48b3d82ffe1ed19db9ba3cf7e6536ecf92e27391.tar.bz2 | |
Squashed 'unittest/Catch/' content from commit ae5ee2cf
git-subtree-dir: unittest/Catch
git-subtree-split: ae5ee2cf63d6d67bd1369b512d2a7b60b571c907
Diffstat (limited to 'include/external/tbc_text_format.h')
| -rw-r--r-- | include/external/tbc_text_format.h | 153 | 
1 files changed, 153 insertions, 0 deletions
| diff --git a/include/external/tbc_text_format.h b/include/external/tbc_text_format.h new file mode 100644 index 0000000..a63d6a1 --- /dev/null +++ b/include/external/tbc_text_format.h @@ -0,0 +1,153 @@ +/* + *  Created by Phil on 18/4/2013. + *  Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + *  Distributed under the Boost Software License, Version 1.0. (See accompanying + *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +// Only use header guard if we are not using an outer namespace +#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +#  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#  endif +# else +#  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# endif +#endif +#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#include <string> +#include <vector> +#include <sstream> + +// Use optional outer namespace +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH +    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else +    const unsigned int consoleWidth = 80; +#endif + +    struct TextAttributes { +        TextAttributes() +        :   initialIndent( std::string::npos ), +            indent( 0 ), +            width( consoleWidth-1 ), +            tabChar( '\t' ) +        {} + +        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; } +        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; } +        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; } +        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; } + +        std::size_t initialIndent;  // indent of first line, or npos +        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos +        std::size_t width;          // maximum width of text, including indent. Longer text will wrap +        char tabChar;               // If this char is seen the indent is changed to current pos +    }; + +    class Text { +    public: +        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) +        : attr( _attr ) +        { +            std::string wrappableChars = " [({.,/|\\-"; +            std::size_t indent = _attr.initialIndent != std::string::npos +                ? _attr.initialIndent +                : _attr.indent; +            std::string remainder = _str; + +            while( !remainder.empty() ) { +                if( lines.size() >= 1000 ) { +                    lines.push_back( "... message truncated due to excessive size" ); +                    return; +                } +                std::size_t tabPos = std::string::npos; +                std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); +                std::size_t pos = remainder.find_first_of( '\n' ); +                if( pos <= width ) { +                    width = pos; +                } +                pos = remainder.find_last_of( _attr.tabChar, width ); +                if( pos != std::string::npos ) { +                    tabPos = pos; +                    if( remainder[width] == '\n' ) +                        width--; +                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); +                } + +                if( width == remainder.size() ) { +                    spliceLine( indent, remainder, width ); +                } +                else if( remainder[width] == '\n' ) { +                    spliceLine( indent, remainder, width ); +                    if( width <= 1 || remainder.size() != 1 ) +                        remainder = remainder.substr( 1 ); +                    indent = _attr.indent; +                } +                else { +                    pos = remainder.find_last_of( wrappableChars, width ); +                    if( pos != std::string::npos && pos > 0 ) { +                        spliceLine( indent, remainder, pos ); +                        if( remainder[0] == ' ' ) +                            remainder = remainder.substr( 1 ); +                    } +                    else { +                        spliceLine( indent, remainder, width-1 ); +                        lines.back() += "-"; +                    } +                    if( lines.size() == 1 ) +                        indent = _attr.indent; +                    if( tabPos != std::string::npos ) +                        indent += tabPos; +                } +            } +        } + +        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { +            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); +            _remainder = _remainder.substr( _pos ); +        } + +        typedef std::vector<std::string>::const_iterator const_iterator; + +        const_iterator begin() const { return lines.begin(); } +        const_iterator end() const { return lines.end(); } +        std::string const& last() const { return lines.back(); } +        std::size_t size() const { return lines.size(); } +        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } +        std::string toString() const { +            std::ostringstream oss; +            oss << *this; +            return oss.str(); +        } + +        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { +            for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); +                it != itEnd; ++it ) { +                if( it != _text.begin() ) +                    _stream << "\n"; +                _stream << *it; +            } +            return _stream; +        } + +    private: +        std::string str; +        TextAttributes attr; +        std::vector<std::string> lines; +    }; + +} // end namespace Tbc + +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED | 
