summaryrefslogtreecommitdiffstats
path: root/source/core/slang-string-util.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-04-28 11:42:22 -0700
committerGitHub <noreply@github.com>2025-04-28 11:42:22 -0700
commitc39c29bf4c52a85d7c83cc8b66ae45e265f9e078 (patch)
tree969339828d49d7db92ed9294a17bd34cc021db84 /source/core/slang-string-util.cpp
parent8f6c6e333c06ae1c3b9f00396563c14a2ae09b4d (diff)
Add Slang Byte Code generation and interpreter. (#6896)
* Add Slang Byte Code generation and interpreter. * Fix compile issues. * format code * More compile fix. * Fix clang issue. * Fix more clang issues. * Another clang fix. * Fix clang issues. * Fix another clang issue. * Fix wasm build. * Update building.md * Fix test-server. * Fix compile error. * Fix bug. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/core/slang-string-util.cpp')
-rw-r--r--source/core/slang-string-util.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index ba234e30b..65758fd14 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -390,6 +390,159 @@ UnownedStringSlice StringUtil::getAtInSplit(
return builder;
}
+template<typename T>
+static T readValue(ArrayView<const void*> ptrToArgs, Count& argIndex)
+{
+ if (argIndex < ptrToArgs.getCount())
+ {
+ T value;
+ memcpy(&value, ptrToArgs[argIndex], sizeof(T));
+ argIndex++;
+ return value;
+ }
+ return T();
+}
+
+String StringUtil::makeStringWithFormatFromArgArray(
+ const char* format,
+ ArrayView<const void*> ptrToArgs)
+{
+ if (!format)
+ {
+ return String();
+ }
+ StringBuilder builder;
+ const char* ptr = format;
+ Count argIndex = 0;
+ auto consumeString = [&]()
+ {
+ if (argIndex < ptrToArgs.getCount())
+ {
+ const char* strPtr = *(const char**)ptrToArgs[argIndex];
+ argIndex++;
+ if (strPtr)
+ {
+ // Append the string to the builder
+ builder.append(strPtr);
+ }
+ }
+ };
+#define ADVANCE_PTR \
+ ptr++; \
+ if (!*ptr) \
+ { \
+ return builder.produceString(); \
+ }
+
+ while (*ptr)
+ {
+ if (*ptr == '%')
+ {
+ const char* formatStart = ptr;
+ ADVANCE_PTR;
+ if (*ptr == 's')
+ {
+ // If we have a %s, then we want to append the data
+ consumeString();
+ // Move past the 's'
+ ADVANCE_PTR;
+ continue;
+ }
+ if (*ptr == '-')
+ {
+ // If we have a %- then we want to continue parsing format string.
+ ADVANCE_PTR;
+ }
+ while (CharUtil::isDigit(*ptr))
+ {
+ // Skip the digits after the '.'
+ ADVANCE_PTR;
+ }
+ if (*ptr == '.')
+ {
+ ADVANCE_PTR;
+ while (CharUtil::isDigit(*ptr))
+ {
+ // Skip the digits after the '.'
+ ADVANCE_PTR;
+ }
+ }
+ int isLong = 0;
+ if (*ptr == 'l' || *ptr == 'L')
+ {
+ // If we have a 'l' or 'L', then we want to skip it.
+ ADVANCE_PTR;
+ isLong = 1;
+ if (*ptr == 'l' || *ptr == 'L')
+ {
+ // If we have another 'l' or 'L', then we want to skip it too.
+ ADVANCE_PTR;
+ isLong = 2;
+ }
+ }
+ const char typeChar = *ptr;
+ ADVANCE_PTR;
+ String formatStr = UnownedStringSlice(formatStart, ptr);
+ switch (CharUtil::toLower(typeChar))
+ {
+ case 'd':
+ case 'x':
+ case 'i':
+ case 'u':
+ case 'o':
+ case 'c':
+ if (isLong == 2)
+ {
+ StringUtil::appendFormat(
+ builder,
+ formatStr.getBuffer(),
+ readValue<int64_t>(ptrToArgs, argIndex));
+ }
+ else
+ {
+ StringUtil::appendFormat(
+ builder,
+ formatStr.getBuffer(),
+ readValue<int>(ptrToArgs, argIndex));
+ }
+ break;
+ case 'e':
+ case 'f':
+ case 'g':
+ if (isLong != 0)
+ {
+ StringUtil::appendFormat(
+ builder,
+ formatStr.getBuffer(),
+ readValue<double>(ptrToArgs, argIndex));
+ }
+ else
+ {
+ StringUtil::appendFormat(
+ builder,
+ formatStr.getBuffer(),
+ readValue<float>(ptrToArgs, argIndex));
+ }
+ break;
+ case 'n':
+ break;
+ case '%':
+ // If we have a '%%' then we want to append a single '%'
+ builder.appendChar('%');
+ continue;
+ }
+ }
+ else
+ {
+ // Just append the character
+ builder.appendChar(*ptr);
+ ptr++;
+ }
+ }
+ return builder.produceString();
+}
+
+
/* static */ UnownedStringSlice StringUtil::getSlice(ISlangBlob* blob)
{
if (blob)