summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-list.h2
-rw-r--r--source/core/slang-string-escape-util.cpp43
-rw-r--r--source/core/slang-string-escape-util.h16
-rw-r--r--source/core/slang-string-util.cpp100
-rw-r--r--source/core/slang-string-util.h6
5 files changed, 162 insertions, 5 deletions
diff --git a/source/core/slang-list.h b/source/core/slang-list.h
index 08d9aa773..4420cc084 100644
--- a/source/core/slang-list.h
+++ b/source/core/slang-list.h
@@ -351,7 +351,7 @@ namespace Slang
void growToCount(Index count)
{
- Index newBufferCount = Index(1) << Math::Log2Ceil(count);
+ Index newBufferCount = Index(1) << Math::Log2Ceil((unsigned int)count);
if (m_capacity < newBufferCount)
{
reserve(newBufferCount);
diff --git a/source/core/slang-string-escape-util.cpp b/source/core/slang-string-escape-util.cpp
index a91d88e05..ffc43a7cb 100644
--- a/source/core/slang-string-escape-util.cpp
+++ b/source/core/slang-string-escape-util.cpp
@@ -18,6 +18,8 @@ public:
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { return isEscapingNeeded(slice); }
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
+ virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
+
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
@@ -30,6 +32,13 @@ bool SpaceStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
return slice.indexOf(' ') >= 0;
}
+bool SpaceStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice)
+{
+ SLANG_UNUSED(slice);
+ // As it stands we never have to unescape
+ return false;
+}
+
SlangResult SpaceStringEscapeHandler::appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
{
if (slice.indexOf('"') >= 0)
@@ -98,6 +107,7 @@ public:
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { SLANG_UNUSED(slice); return true; }
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
+ virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
@@ -167,6 +177,12 @@ static char _getCppUnescapedChar(char c)
}
}
+
+bool CppStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice)
+{
+ return slice.indexOf('\\') >= 0;
+}
+
/* static */bool CppStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
{
const char* cur = slice.begin();
@@ -456,6 +472,7 @@ public:
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { SLANG_UNUSED(slice); return true; }
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
+ virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
@@ -463,6 +480,11 @@ public:
JSONStringEscapeHandler() : Super('"') {}
};
+bool JSONStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice)
+{
+ return slice.indexOf('\\') >= 0;
+}
+
bool JSONStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
{
const char* cur = slice.begin();
@@ -868,6 +890,23 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
}
}
+/* static */bool StringEscapeUtil::isQuoted(char quoteChar, UnownedStringSlice& slice)
+{
+ const Index len = slice.getLength();
+ return len >= 2 && slice[0] == quoteChar && slice[len - 1] == quoteChar;
+}
+
+/* static */UnownedStringSlice StringEscapeUtil::unquote(char quoteChar, const UnownedStringSlice& slice)
+{
+ const Index len = slice.getLength();
+ if (len >= 2 && slice[0] == quoteChar && slice[len - 1] == quoteChar)
+ {
+ return UnownedStringSlice(slice.begin() + 1, len - 2);
+ }
+ SLANG_ASSERT(!"Not quoted!");
+ return UnownedStringSlice();
+}
+
/* static */SlangResult StringEscapeUtil::appendMaybeUnquoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
{
const char quoteChar = handler->getQuoteChar();
@@ -885,6 +924,10 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
}
}
+/* static */SlangResult StringEscapeUtil::isUnescapeShellLikeNeeded(Handler* handler, const UnownedStringSlice& slice)
+{
+ return slice.indexOf(handler->getQuoteChar()) >= 0;
+}
/* static */SlangResult StringEscapeUtil::unescapeShellLike(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
{
diff --git a/source/core/slang-string-escape-util.h b/source/core/slang-string-escape-util.h
index c3039eb47..5f749c423 100644
--- a/source/core/slang-string-escape-util.h
+++ b/source/core/slang-string-escape-util.h
@@ -14,6 +14,9 @@ public:
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) = 0;
/// True if any escaping is needed. If not slice can be used (assuming appropriate quoting) as is
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) = 0;
+ /// True if we need to unescape
+ virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) = 0;
+
/// Takes slice and adds any appropriate escaping (for example C++/C type escaping for special characters like '\', '"' and if not ascii will write out as hex sequence)
/// Does not append quotes
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) = 0;
@@ -57,6 +60,14 @@ struct StringEscapeUtil
/// Given a style returns a handler
static Handler* getHandler(Style style);
+ /// Get without quotes. Will assert if not correctly quoted
+ static UnownedStringSlice unquote(char quoteChar, const UnownedStringSlice& slice);
+ static UnownedStringSlice unquote(Handler* handler, const UnownedStringSlice& slice) { return unquote(handler->getQuoteChar(), slice); }
+
+ /// True is slice is quoted
+ static bool isQuoted(char quoteChar, UnownedStringSlice& slice);
+ static bool isQuoted(Handler* handler, UnownedStringSlice& slice) { return isQuoted(handler->getQuoteChar(), slice); }
+
/// If quoting is needed appends to out quoted
static SlangResult appendMaybeQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
@@ -69,6 +80,11 @@ struct StringEscapeUtil
/// Append with quotes (even if not needed)
static SlangResult appendQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
+
+ /// True if requires 'shell-like' unescape. With shell-like, quoting does *not* have to start at the start of the slice.
+ /// and there may be multiple quoted section
+ static SlangResult isUnescapeShellLikeNeeded(Handler* handler, const UnownedStringSlice& slice);
+
/// Shells can have multiple quoted sections. This function makes a string with out quoting
static SlangResult unescapeShellLike(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
};
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index 7a142f643..b2886c413 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -458,9 +458,31 @@ ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
}
}
-SLANG_FORCE_INLINE static bool _isDigit(char c)
+/* static */SlangResult StringUtil::parseDouble(const UnownedStringSlice& text, double& out)
{
- return (c >= '0' && c <= '9');
+ const Index bufSize = 32;
+
+ const auto len = text.getLength();
+
+ if (len > bufSize - 1)
+ {
+ List<char> work;
+ work.setCount(len + 1);
+ char* dst = work.getBuffer();
+
+ ::memcpy(dst, text.begin(), len * sizeof(char));
+ dst[len] = 0;
+
+ out = atof(dst);
+ }
+ else
+ {
+ char buf[bufSize];
+ ::memcpy(buf, text.begin(), len * sizeof(char));
+ buf[len] = 0;
+ out = atof(buf);
+ }
+ return SLANG_OK;
}
/* static */SlangResult StringUtil::parseInt(const UnownedStringSlice& in, Int& outValue)
@@ -476,7 +498,7 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
}
// We need at least one digit
- if (cur >= end || !_isDigit(*cur))
+ if (cur >= end || !CharUtil::isDigit(*cur))
{
return SLANG_FAIL;
}
@@ -486,7 +508,7 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
for (; cur < end; ++cur)
{
const char c = *cur;
- if (!_isDigit(c))
+ if (!CharUtil::isDigit(c))
{
return SLANG_FAIL;
}
@@ -499,4 +521,74 @@ SLANG_FORCE_INLINE static bool _isDigit(char c)
return SLANG_OK;
}
+/* static */SlangResult StringUtil::parseInt64(const UnownedStringSlice& text, int64_t& out)
+{
+ bool negate = false;
+
+ const char* cur = text.begin();
+ const char* end = text.end();
+
+ if (cur < end)
+ {
+ if (*cur == '-')
+ {
+ negate = true;
+ cur++;
+ }
+ else if (*cur == '+')
+ {
+ cur++;
+ }
+ }
+
+ // Must have at least one digit
+ if (cur >= end || !CharUtil::isDigit(*cur))
+ {
+ return SLANG_FAIL;
+ }
+
+ uint64_t value = 0;
+ // We can have 20 digits, but the last digit can cause overflow.
+ // Lets do the easy first digits first
+ Index numSimple = 19;
+ for (; cur < end && CharUtil::isDigit(*cur) && numSimple > 0; ++cur, --numSimple)
+ {
+ value = value * 10 + (*cur - '0');
+ }
+
+ if (cur < end && CharUtil::isDigit(*cur))
+ {
+ const auto prevValue = value;
+ value = value * 10 + (*cur - '0');
+ cur++;
+
+ if (value < prevValue)
+ {
+ // We have overflow
+ return SLANG_FAIL;
+ }
+ }
+
+ if (negate)
+ {
+ if (value > ~((~uint64_t(0)) >> 1))
+ {
+ // Overflow
+ return SLANG_FAIL;
+ }
+ out = -int64_t(value);
+ }
+ else
+ {
+ if (value > ((~uint64_t(0)) >> 1))
+ {
+ // Overflow
+ return SLANG_FAIL;
+ }
+ out = value;
+ }
+
+ return (cur == end) ? SLANG_OK : SLANG_FAIL;
+}
+
} // namespace Slang
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index 2b30120b7..6a0794082 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -100,6 +100,12 @@ struct StringUtil
/// Convert in to int. Returns SLANG_FAIL on error
static SlangResult parseInt(const UnownedStringSlice& in, Int& outValue);
+
+ /// Convert ioText into double. Returns SLANG_OK on success.
+ static SlangResult parseDouble(const UnownedStringSlice& text, double& out);
+
+ /// Convert into int64_t. Returns SLANG_OK on success.
+ static SlangResult parseInt64(const UnownedStringSlice& text, int64_t& out);
};
/* A helper class that allows parsing of lines from text with iteration. Uses StringUtil::extractLine for the actual underlying implementation. */