| 3248 | namespace Catch { |
| 3249 | |
| 3250 | class TestSpecParser { |
| 3251 | enum Mode{ None, Name, QuotedName, Tag }; |
| 3252 | Mode m_mode; |
| 3253 | bool m_exclusion; |
| 3254 | std::size_t m_start, m_pos; |
| 3255 | std::string m_arg; |
| 3256 | TestSpec::Filter m_currentFilter; |
| 3257 | TestSpec m_testSpec; |
| 3258 | ITagAliasRegistry const* m_tagAliases; |
| 3259 | |
| 3260 | public: |
| 3261 | TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} |
| 3262 | |
| 3263 | TestSpecParser& parse( std::string const& arg ) { |
| 3264 | m_mode = None; |
| 3265 | m_exclusion = false; |
| 3266 | m_start = std::string::npos; |
| 3267 | m_arg = m_tagAliases->expandAliases( arg ); |
| 3268 | for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) |
| 3269 | visitChar( m_arg[m_pos] ); |
| 3270 | if( m_mode == Name ) |
| 3271 | addPattern<TestSpec::NamePattern>(); |
| 3272 | return *this; |
| 3273 | } |
| 3274 | TestSpec testSpec() { |
| 3275 | addFilter(); |
| 3276 | return m_testSpec; |
| 3277 | } |
| 3278 | private: |
| 3279 | void visitChar( char c ) { |
| 3280 | if( m_mode == None ) { |
| 3281 | switch( c ) { |
| 3282 | case ' ': return; |
| 3283 | case '~': m_exclusion = true; return; |
| 3284 | case '[': return startNewMode( Tag, ++m_pos ); |
| 3285 | case '"': return startNewMode( QuotedName, ++m_pos ); |
| 3286 | default: startNewMode( Name, m_pos ); break; |
| 3287 | } |
| 3288 | } |
| 3289 | if( m_mode == Name ) { |
| 3290 | if( c == ',' ) { |
| 3291 | addPattern<TestSpec::NamePattern>(); |
| 3292 | addFilter(); |
| 3293 | } |
| 3294 | else if( c == '[' ) { |
| 3295 | if( subString() == "exclude:" ) |
| 3296 | m_exclusion = true; |
| 3297 | else |
| 3298 | addPattern<TestSpec::NamePattern>(); |
| 3299 | startNewMode( Tag, ++m_pos ); |
| 3300 | } |
| 3301 | } |
| 3302 | else if( m_mode == QuotedName && c == '"' ) |
| 3303 | addPattern<TestSpec::NamePattern>(); |
| 3304 | else if( m_mode == Tag && c == ']' ) |
| 3305 | addPattern<TestSpec::TagPattern>(); |
| 3306 | } |
| 3307 | void startNewMode( Mode mode, std::size_t start ) { |
no test coverage detected