| 5005 | namespace Catch { |
| 5006 | |
| 5007 | class TestSpecParser { |
| 5008 | enum Mode{ None, Name, QuotedName, Tag, EscapedName }; |
| 5009 | Mode m_mode = None; |
| 5010 | bool m_exclusion = false; |
| 5011 | std::size_t m_pos = 0; |
| 5012 | std::string m_arg; |
| 5013 | std::string m_substring; |
| 5014 | std::string m_patternName; |
| 5015 | std::vector<std::size_t> m_escapeChars; |
| 5016 | TestSpec::Filter m_currentFilter; |
| 5017 | TestSpec m_testSpec; |
| 5018 | ITagAliasRegistry const* m_tagAliases = nullptr; |
| 5019 | |
| 5020 | public: |
| 5021 | TestSpecParser( ITagAliasRegistry const& tagAliases ); |
| 5022 | |
| 5023 | TestSpecParser& parse( std::string const& arg ); |
| 5024 | TestSpec testSpec(); |
| 5025 | |
| 5026 | private: |
| 5027 | void visitChar( char c ); |
| 5028 | void startNewMode( Mode mode ); |
| 5029 | bool processNoneChar( char c ); |
| 5030 | void processNameChar( char c ); |
| 5031 | bool processOtherChar( char c ); |
| 5032 | void endMode(); |
| 5033 | void escape(); |
| 5034 | bool isControlChar( char c ) const; |
| 5035 | |
| 5036 | template<typename T> |
| 5037 | void addPattern() { |
| 5038 | std::string token = m_patternName; |
| 5039 | for( std::size_t i = 0; i < m_escapeChars.size(); ++i ) |
| 5040 | token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 ); |
| 5041 | m_escapeChars.clear(); |
| 5042 | if( startsWith( token, "exclude:" ) ) { |
| 5043 | m_exclusion = true; |
| 5044 | token = token.substr( 8 ); |
| 5045 | } |
| 5046 | if( !token.empty() ) { |
| 5047 | TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring ); |
| 5048 | if( m_exclusion ) |
| 5049 | pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern ); |
| 5050 | m_currentFilter.m_patterns.push_back( pattern ); |
| 5051 | } |
| 5052 | m_substring.clear(); |
| 5053 | m_patternName.clear(); |
| 5054 | m_exclusion = false; |
| 5055 | m_mode = None; |
| 5056 | } |
| 5057 | |
| 5058 | void addFilter(); |
| 5059 | }; |
| 5060 | TestSpec parseTestSpec( std::string const& arg ); |
| 5061 | |
| 5062 | } // namespace Catch |