static void sReadQuotedString_Apos(const ZStrimU& iStrimU, ZTupleValue& oTupleValue) { using namespace ZUtil_Strim; string theString; theString.reserve(100); ZStrimW_String theStrimW(theString); for (;;) { sCopy_EscapedString(iStrimU, '\'', theStrimW); if (!sTryRead_CP(iStrimU, '\'')) throw ParseException("Expected ' to close a string"); sSkip_WSAndCPlusPlusComments(iStrimU); if (!sTryRead_CP(iStrimU, '\'')) break; } oTupleValue.SetString(theString); }
static void sReadQuotedString_Quote(const ZStrimU& iStrimU, ZTupleValue& oTupleValue) { using namespace ZUtil_Strim; string theString; theString.reserve(100); ZStrimW_String theStrimW(theString); for (;;) { // We've read, and could un-read, a quote mark. if (sTryRead_CP(iStrimU, '"')) { // We've now seen a second quote, abutting the first. if (sTryRead_CP(iStrimU, '"')) { // We have three quotes in a row, which opens a verbatim string. // If the next character is an EOL then absorb it, so the verbatim // text can start on a fresh line, but not be parsed as // beginning with an EOL. UTF32 theCP = iStrimU.ReadCP(); if (!ZUnicode::sIsEOL(theCP)) iStrimU.Unread(); // Now copy everything till we see three quotes in a row again. ZStrimR_Boundary theStrimR_Boundary("\"\"\"", iStrimU); theStrimW.CopyAllFrom(theStrimR_Boundary); if (!theStrimR_Boundary.HitBoundary()) throw ParseException("Expected \"\"\" to close a string"); if (sTryRead_CP(iStrimU, '"')) { // We have another quote, so there were at least four in a row, // which we get with a quote in the text immediately followed // by the triple quote. So emit a quote. theStrimW.WriteCP('"'); if (sTryRead_CP(iStrimU, '"')) { // Same again -- five quotes in a row, which is two content // quotes followed by the closing triple. theStrimW.WriteCP('"'); // This is why it's essential that when using triple quotes // you put whitespace before the opening, and after the closing // triple, so we don't mistake included quotes for ones that // are (say) opening a subsequent regular quoted sequence. } } } else { // We have two quotes in a row, followed by something else, so // we had an empty string segment. } } else { sCopy_EscapedString(iStrimU, '"', theStrimW); if (!sTryRead_CP(iStrimU, '"')) throw ParseException("Expected \" to close a string"); } sSkip_WSAndCPlusPlusComments(iStrimU); if (!sTryRead_CP(iStrimU, '"')) break; } oTupleValue.SetString(theString); }