Allow quotes in CAPTURE arguments
Simple fix to allow CAPTURE to handle string with comma. Also ignores
brackets in string. No quotation mark escaping is implemented, so `"\""`
and `'"'` will still fail.

Fixes #1607 

I can improve parsing algorithm to handle single and double quotes correctly, but that is probably overkill ...



{"label": "catchorg:master", "ref": "master", "sha": "979bbf03bb00bc55ca09783791b5091a2247df68"}
**Describe the bug**
When string containing comma is passed to CAPTURE and test succeeds, the program will fail assertion 
`Capturer::~Capturer() : assert( m_captured == m_messages.size() );`

**Expected behavior**
Documenting this behavior is probably enough. CAPTURE(("test, with comma")) works as expected. 

**Reproduction steps**
```
TEST_CASE("catch") {
  CAPTURE("test, with comma");
  CHECK(false);
  CAPTURE("test, with comma");
  CHECK(true);
}
```
produces:
```
test/test_suite.cpp:35: FAILED:
  CHECK( false )
with message:
  "test := "test, with comma"

test_suite: test/catch.hpp:9638: Catch::Capturer::~Capturer(): Assertion `m_captured == m_messages.size()' failed.
```
**Platform information:**
<!-- Fill in any extra information that might be important for your issue. -->
 - OS: **Debian stretch**
 - Compiler+version: **gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516**
 - Catch version: **Catch v2.7.0**


**Additional context**
Capturer::Capturer() does not expect quotation in names. It should be quite easy to fix (just add `bool isquoted` into parsing algorithm.

BTW: Capturing string is quite useful when capturing __VA_ARGS__ in macro ... 

CAPTURE("text, with comma") fails
diff --git a/include/internal/catch_message.cpp b/include/internal/catch_message.cpp
index fa7e874614..69e48211f6 100644
--- a/include/internal/catch_message.cpp
+++ b/include/internal/catch_message.cpp
@@ -9,6 +9,7 @@
 #include "catch_message.h"
 #include "catch_interfaces_capture.h"
 #include "catch_uncaught_exceptions.h"
+#include "catch_enforce.h"
 
 #include <cassert>
 #include <stack>
@@ -76,6 +77,15 @@ namespace Catch {
             }
             return names.substr(start, end - start + 1);
         };
+        auto skipq = [&] (size_t start, char quote) {
+            for (auto i = start + 1; i < names.size() ; ++i) {
+                if (names[i] == quote)
+                    return i;
+                if (names[i] == '\\')
+                    ++i;
+            }
+            CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched parentheses");
+        };
 
         size_t start = 0;
         std::stack<char> openings;
@@ -96,6 +106,10 @@ namespace Catch {
 //           case '>':
                 openings.pop();
                 break;
+            case '"':
+            case '\'':
+                pos = skipq(pos, c);
+                break;
             case ',':
                 if (start != pos && openings.size() == 0) {
                     m_messages.emplace_back(macroName, lineInfo, resultType);
diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt
index 3755dd955d..259954e4b8 100644
--- a/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -230,6 +230,7 @@ Tricky.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
 Tricky.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
 Message.tests.cpp:<line number>: passed: with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a + b := 3' and 'a+b := 3' and 'c > b := true' and 'a == 1 := true'
 Message.tests.cpp:<line number>: passed: with 7 messages: 'std::vector<int>{1, 2, 3}[0, 1, 2] := 3' and 'std::vector<int>{1, 2, 3}[(0, 1)] := 2' and 'std::vector<int>{1, 2, 3}[0] := 1' and '(helper_1436<int, int>{12, -12}) := { 12, -12 }' and '(helper_1436<int, int>(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
+Message.tests.cpp:<line number>: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
 ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: 'i := 2'
 ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: '3'
 ToStringGeneral.tests.cpp:<line number>: passed: tab == '\t' for: '\t' == '\t'
diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt
index 8e86cb2eeb..0a4de92369 100644
--- a/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/projects/SelfTest/Baselines/console.std.approved.txt
@@ -1299,6 +1299,6 @@ due to unexpected exception with message:
   Why would you throw a std::string?
 
 ===============================================================================
-test cases:  265 |  198 passed |  63 failed |  4 failed as expected
-assertions: 1448 | 1303 passed | 124 failed | 21 failed as expected
+test cases:  266 |  199 passed |  63 failed |  4 failed as expected
+assertions: 1449 | 1304 passed | 124 failed | 21 failed as expected
 
diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt
index d5c143b256..2b998afc7e 100644
--- a/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -1786,6 +1786,27 @@ with messages:
   (1, 2) := 2
   (2, 3) := 3
 
+-------------------------------------------------------------------------------
+CAPTURE parses string and character constants
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+with messages:
+  ("comma, in string", "escaped, \", ") := "escaped, ", "
+  "single quote in string,'," := "single quote in string,',"
+  "some escapes, \\,\\\\" := "some escapes, \,\\"
+  "some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[
+  <"
+  '"' := '"'
+  '\'' := '''
+  ',' := ','
+  '}' := '}'
+  ')' := ')'
+  '(' := '('
+  '{' := '{'
+
 -------------------------------------------------------------------------------
 Capture and info messages
   Capture should stringify like assertions
@@ -11368,6 +11389,6 @@ Misc.tests.cpp:<line number>
 Misc.tests.cpp:<line number>: PASSED:
 
 ===============================================================================
-test cases:  265 |  182 passed |  79 failed |  4 failed as expected
-assertions: 1465 | 1303 passed | 141 failed | 21 failed as expected
+test cases:  266 |  183 passed |  79 failed |  4 failed as expected
+assertions: 1466 | 1304 passed | 141 failed | 21 failed as expected
 
diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt
index 709171f205..7f4b43dbb1 100644
--- a/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuitesloose text artifact
 >
-  <testsuite name="<exe-name>" errors="17" failures="125" tests="1466" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="125" tests="1467" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <properties>
       <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
       <property name="random-seed" value="1"/>
@@ -189,6 +189,7 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Bitfields can be captured (#1027)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions involving commas" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="CAPTURE parses string and character constants" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Capture and info messages/Capture should stringify like assertions" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Capture and info messages/Info should NOT stringify the way assertions do" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt
index c704406ff7..fa078ac800 100644
--- a/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -2049,6 +2049,42 @@ Nor would this
       </Info>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="CAPTURE parses string and character constants" tags="[capture][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
+      <Info>
+        ("comma, in string", "escaped, \", ") := "escaped, ", "
+      </Info>
+      <Info>
+        "single quote in string,'," := "single quote in string,',"
+      </Info>
+      <Info>
+        "some escapes, \\,\\\\" := "some escapes, \,\\"
+      </Info>
+      <Info>
+        "some, ), unmatched, } prenheses {[&lt;" := "some, ), unmatched, } prenheses {[&lt;"
+      </Info>
+      <Info>
+        '"' := '"'
+      </Info>
+      <Info>
+        '\'' := '''
+      </Info>
+      <Info>
+        ',' := ','
+      </Info>
+      <Info>
+        '}' := '}'
+      </Info>
+      <Info>
+        ')' := ')'
+      </Info>
+      <Info>
+        '(' := '('
+      </Info>
+      <Info>
+        '{' := '{'
+      </Info>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Capture and info messages" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
       <Section name="Capture should stringify like assertions" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
         <Info>
@@ -13692,7 +13728,7 @@ loose text artifact
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="1303" failures="142" expectedFailures="21"/>
+    <OverallResults successes="1304" failures="142" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="1303" failures="141" expectedFailures="21"/>
+  <OverallResults successes="1304" failures="141" expectedFailures="21"/>
 </Catch>

diff --git a/projects/SelfTest/UsageTests/Message.tests.cpp b/projects/SelfTest/UsageTests/Message.tests.cpp
index ccb7ac2f0c..933470845b 100644
--- a/projects/SelfTest/UsageTests/Message.tests.cpp
+++ b/projects/SelfTest/UsageTests/Message.tests.cpp
@@ -251,6 +251,13 @@ TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messag
     SUCCEED();
 }
 
+TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
+    CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
+    CAPTURE("some, ), unmatched, } prenheses {[<");
+    CAPTURE('"', '\'', ',', '}', ')', '(', '{');
+    SUCCEED();
+}
+
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif

{"approvaltests": {"run": "PASS", "test": "FAIL", "fix": "PASS"}, "noassertions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtests": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"listtags": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "listtests": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "notest": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filteredsection-1": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "listtestnamesonly": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "filteredsection-2": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "listreporters": {"run": "PASS", "test": "PASS", "fix": "PASS"}}
{"noassertions": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "runtests": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 10, "failed_count": 0, "skipped_count": 0, "passed_tests": ["approvaltests", "noassertions", "runtests", "listtags", "listreporters", "listtests", "notest", "filteredsection-1", "filteredsection-2", "listtestnamesonly"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 7, "failed_count": 1, "skipped_count": 0, "passed_tests": ["listtags", "listreporters", "listtests", "notest", "filteredsection-1", "filteredsection-2", "listtestnamesonly"], "failed_tests": ["approvaltests"], "skipped_tests": []}
{"passed_count": 10, "failed_count": 0, "skipped_count": 0, "passed_tests": ["approvaltests", "noassertions", "runtests", "listtags", "listreporters", "listtests", "notest", "filteredsection-1", "filteredsection-2", "listtestnamesonly"], "failed_tests": [], "skipped_tests": []}