From 91d5448a5ae4ec942eb1e3644d3e3f274425f42a Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Fri, 13 Aug 2010 00:48:05 -0400 Subject: [PATCH] Enhancement - Nibbler - Added Nibbler::getQuoted with support for unescaping escaped quotes and for including the original quotes. --- src/Nibbler.cpp | 69 ++++++++++++++++++++++++++++++++++++----- src/Nibbler.h | 2 +- src/tests/nibbler.t.cpp | 26 ++++++++++++++-- 3 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/Nibbler.cpp b/src/Nibbler.cpp index b895151e3..ddefbc561 100644 --- a/src/Nibbler.cpp +++ b/src/Nibbler.cpp @@ -210,18 +210,71 @@ bool Nibbler::getUntilEOS (std::string& result) } //////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getQuoted (char c, std::string& result) +bool Nibbler::getQuoted ( + char c, + std::string& result, + bool unescape /* = true */, + bool quote /* = false */) { - std::string::size_type backup = mCursor; - - if (skip (c) && - getUntil (c, result) && - skip (c)) + if (mCursor < mLength) { - return true; + if (mInput[mCursor] != c) + return false; + + result = ""; + bool inquote = false; + char current = 0; + char previous = 0; + + // '"' + // p c + // - - + // ' + // ' " + // " ' + for (std::string::size_type i = mCursor; i < mLength; ++i) + { + previous = current; + current = mInput[i]; + + if (current == c) + { + if (previous == '\\') + { + if (!unescape) + result += previous; + + result += current; + } + else + { + if (!inquote) + { + inquote = true; + if (quote) + result += current; + } + else + { + if (quote) + result += current; + + mCursor = i + 1; + return true; + } + } + } + else if (current == '\\') + { + // NOP + } + else + { + result += current; + } + } } - mCursor = backup; return false; } diff --git a/src/Nibbler.h b/src/Nibbler.h index 8a5fddf23..fe318dc57 100644 --- a/src/Nibbler.h +++ b/src/Nibbler.h @@ -47,7 +47,7 @@ public: bool getUntilEOL (std::string&); bool getUntilEOS (std::string&); - bool getQuoted (char, std::string&); + bool getQuoted (char, std::string&, bool unescape = true, bool quote = false); bool getInt (int&); bool getUnsignedInt (int&); bool getLiteral (const std::string&); diff --git a/src/tests/nibbler.t.cpp b/src/tests/nibbler.t.cpp index 3a1f754cd..3850b9c27 100644 --- a/src/tests/nibbler.t.cpp +++ b/src/tests/nibbler.t.cpp @@ -33,7 +33,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (140); + UnitTest t (149); try { @@ -176,11 +176,11 @@ int main (int argc, char** argv) n = Nibbler ("'\"'"); t.ok (n.getQuoted ('\'', s), " ''\"'' : getQuoted (''') -> true"); - t.is (s, "\"", " ''\"'' : getQuoted (''') -> '\"'"); + t.is (s, "\"", " ''\"'' : getQuoted (''') -> '\"'"); // 81 n = Nibbler ("'x'"); t.ok (n.getQuoted ('\'', s), " ''x'' : getQuoted (''') -> true"); - t.is (s, "x", " ''x'' : getQuoted (''') -> ''"); + t.is (s, "x", " ''x'' : getQuoted (''') -> ''"); // 83 n = Nibbler ("'x"); t.notok (n.getQuoted ('\'', s), " ''x' : getQuoted (''') -> false"); @@ -188,6 +188,26 @@ int main (int argc, char** argv) n = Nibbler ("x"); t.notok (n.getQuoted ('\'', s), " 'x' : getQuoted (''') -> false"); + n = Nibbler ("\"one\\\"two\""); + t.notok (n.getQuoted ('\'', s), "\"one\\\"two\" : getQuoted (''') -> false"); // 86 + + n = Nibbler ("\"one\\\"two\""); + t.ok (n.getQuoted ('"', s, false, false), "\"one\\\"two\" : getQuoted ('\"', false, false) -> true"); // 87 + t.is (s, "one\\\"two", "getQuoted ('\"', false, false) -> one\\\"two"); // 88 + + n = Nibbler ("\"one\\\"two\""); + t.ok (n.getQuoted ('"', s, false, true), "\"one\\\"two\" : getQuoted ('\"', false, true) -> true"); // 89 + t.is (s, "\"one\\\"two\"", "getQuoted ('\"', false, true) -> \"one\\\"two\""); // 90 + + n = Nibbler ("\"one\\\"two\""); + t.ok (n.getQuoted ('"', s, true, false), "\"one\\\"two\" : getQuoted ('\"', true, false) -> true"); // 91 + t.is (s, "one\"two", "getQuoted ('\"', true, false) -> one\"two"); // 92 + + n = Nibbler ("\"one\\\"two\""); + t.ok (n.getQuoted ('"', s, true, true), "\"one\\\"two\" : getQuoted ('\"', true, true) -> true"); // 93 + t.is (s, "\"one\"two\"", "getQuoted ('\"', true, true) -> \"one\"two\""); // 94 + + // bool getInt (int&); t.diag ("Nibbler::getInt"); n = Nibbler ("123 -4");