| 3053 | namespace Catch { |
| 3054 | |
| 3055 | class TestSpecParser { |
| 3056 | enum Mode { None, Name, QuotedName, Tag, EscapedName }; |
| 3057 | Mode m_mode = None; |
| 3058 | bool m_exclusion = false; |
| 3059 | std::size_t m_start = std::string::npos, m_pos = 0; |
| 3060 | std::string m_arg; |
| 3061 | std::vector<std::size_t> m_escapeChars; |
| 3062 | TestSpec::Filter m_currentFilter; |
| 3063 | TestSpec m_testSpec; |
| 3064 | ITagAliasRegistry const *m_tagAliases = nullptr; |
| 3065 | |
| 3066 | public: |
| 3067 | TestSpecParser(ITagAliasRegistry const &tagAliases); |
| 3068 | |
| 3069 | TestSpecParser &parse(std::string const &arg); |
| 3070 | TestSpec testSpec(); |
| 3071 | |
| 3072 | private: |
| 3073 | void visitChar(char c); |
| 3074 | void startNewMode(Mode mode, std::size_t start); |
| 3075 | void escape(); |
| 3076 | std::string subString() const; |
| 3077 | |
| 3078 | template <typename T> void addPattern() { |
| 3079 | std::string token = subString(); |
| 3080 | for (std::size_t i = 0; i < m_escapeChars.size(); ++i) |
| 3081 | token = token.substr(0, m_escapeChars[i] - m_start - i) + token.substr(m_escapeChars[i] - m_start - i + 1); |
| 3082 | m_escapeChars.clear(); |
| 3083 | if (startsWith(token, "exclude:")) { |
| 3084 | m_exclusion = true; |
| 3085 | token = token.substr(8); |
| 3086 | } |
| 3087 | if (!token.empty()) { |
| 3088 | TestSpec::PatternPtr pattern = std::make_shared<T>(token); |
| 3089 | if (m_exclusion) |
| 3090 | pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern); |
| 3091 | m_currentFilter.m_patterns.push_back(pattern); |
| 3092 | } |
| 3093 | m_exclusion = false; |
| 3094 | m_mode = None; |
| 3095 | } |
| 3096 | |
| 3097 | void addFilter(); |
| 3098 | }; |
| 3099 | TestSpec parseTestSpec(std::string const &arg); |
| 3100 | |
| 3101 | } // namespace Catch |
no outgoing calls