mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-07-07 20:06:39 +02:00
Pig: Added ::getQuoted
This commit is contained in:
parent
ab9d0606fd
commit
2590a48bfc
2 changed files with 61 additions and 0 deletions
60
src/Pig.cpp
60
src/Pig.cpp
|
@ -293,6 +293,66 @@ bool Pig::getNumber (double& result)
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Gets quote content: "foobar" -> foobar (for c = '"')
|
||||
// Handles escaped quotes: "foo\"bar" -> foo\"bar (for c = '"')
|
||||
// Returns false if first character is not c, or if there is no closing c.
|
||||
// Does not modify content between quotes.
|
||||
bool Pig::getQuoted (int quote, std::string& result)
|
||||
{
|
||||
if (! _text[_cursor] ||
|
||||
_text[_cursor] != quote)
|
||||
return false;
|
||||
|
||||
auto start = _cursor + utf8_sequence (quote);
|
||||
auto i = start;
|
||||
|
||||
while (_text[i])
|
||||
{
|
||||
i = _text.find (quote, i);
|
||||
if (i == std::string::npos)
|
||||
return false; // Unclosed quote. Short cut, not definitive.
|
||||
|
||||
if (i == start)
|
||||
{
|
||||
// Empty quote
|
||||
_cursor += 2 * utf8_sequence (quote); // Skip both quote chars
|
||||
result = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_text[i - 1] == '\\')
|
||||
{
|
||||
// Check for escaped backslashes. Backtracking like this is not very
|
||||
// efficient, but is only done in extreme corner cases.
|
||||
|
||||
auto j = i - 2; // Start one character further left
|
||||
bool is_escaped_quote = true;
|
||||
while (j >= start && _text[j] == '\\')
|
||||
{
|
||||
// Toggle flag for each further backslash encountered.
|
||||
is_escaped_quote = is_escaped_quote ? false : true;
|
||||
--j;
|
||||
}
|
||||
|
||||
if (is_escaped_quote)
|
||||
{
|
||||
// Keep searching
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// None of the above applied, we must have found the closing quote char.
|
||||
result.assign (_text, start, i - start);
|
||||
_cursor = i + utf8_sequence (quote); // Skip closing quote char
|
||||
return true;
|
||||
}
|
||||
|
||||
// This should never be reached. We could throw here instead.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Assumes that the options are sorted by decreasing length, so that if the
|
||||
// options contain 'fourteen' and 'four', the stream is first matched against
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
bool getHexDigit (int&);
|
||||
bool getNumber (std::string&);
|
||||
bool getNumber (double&);
|
||||
bool getQuoted (int, std::string&);
|
||||
bool getOneOf (const std::vector <std::string>&, std::string&);
|
||||
bool getRemainder (std::string&);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue