summaryrefslogtreecommitdiffstats
path: root/source/core/slang-hex-dump-util.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-07-17 10:26:37 -0400
committerGitHub <noreply@github.com>2019-07-17 10:26:37 -0400
commit749634a2a6e03acf435c39f78b933a01b90a7440 (patch)
tree950203d3fc29610428b0ca03eb756911b9b11f47 /source/core/slang-hex-dump-util.cpp
parentf52f5cd4a7b5b71617b949fc62a78abe8c4822b3 (diff)
Slang -> C++ -> SharedLibrary -> Test (#999)
* WIP: Adding support for C/C++ compilation to slang API. * Removed BackEndType in test harness -> use SlangPassThrough to identify backends Only require stage for targets that require it. Detection of all different backends. * Windows/Unix create temporary filename. * WIP: Output CPU binaries. * Added a pass-through c/c++ test. * Compile C++/C and store in temporary file. * Read the binary back into memory. * Set debug info and optimization flags for C/C++. Make the CPPCompiler debug/optimization levels match slangs. * Handling of include paths and math precision. * Dumping c++/c source and exe/shared library. * Put hex dump into own util. * End to end pass through c compilation test. * WIP: Simple execute test working on Linux/Unix. * Fix typo on linux. * WIP: To compile slang to cpp shared library. Report backend compiler errors. * Compiles slang -> cpp and loads as shared library. * Fix problem on c-cross-compile test because prelude is now included with <> quotes. * Run slang generated cpp code - using hard coded data. * Added cpp-execute-simple, and test output. * Fix warning that broke win32 build. * Fix compilation problem on osx.
Diffstat (limited to 'source/core/slang-hex-dump-util.cpp')
-rw-r--r--source/core/slang-hex-dump-util.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/source/core/slang-hex-dump-util.cpp b/source/core/slang-hex-dump-util.cpp
new file mode 100644
index 000000000..908f6c1b6
--- /dev/null
+++ b/source/core/slang-hex-dump-util.cpp
@@ -0,0 +1,183 @@
+// slang-hex-dump-util.cpp
+#include "slang-hex-dump-util.h"
+
+#include "slang-common.h"
+#include "slang-string-util.h"
+#include "slang-writer.h"
+
+#include "../../slang-com-helper.h"
+
+namespace Slang
+{
+
+static const UnownedStringSlice s_start = UnownedStringSlice::fromLiteral("--START--");
+static const UnownedStringSlice s_end = UnownedStringSlice::fromLiteral("--END--");
+
+/* static */SlangResult HexDumpUtil::dumpWithMarkers(const List<uint8_t>& data, int maxBytesPerLine, ISlangWriter* writer)
+{
+ WriterHelper helper(writer);
+ SLANG_RETURN_ON_FAIL(helper.write(s_start.begin(), s_start.size()));
+ SLANG_RETURN_ON_FAIL(helper.print(" (%zu)\n", size_t(data.getCount())));
+
+ SLANG_RETURN_ON_FAIL(dump(data, maxBytesPerLine, writer));
+
+ SLANG_RETURN_ON_FAIL(helper.write(s_end.begin(), s_end.size()));
+ SLANG_RETURN_ON_FAIL(helper.put("\n"));
+ return SLANG_OK;
+}
+
+/* static */SlangResult HexDumpUtil::dump(const List<uint8_t>& data, int maxBytesPerLine, ISlangWriter* writer)
+{
+ int maxCharsPerLine = 2 * maxBytesPerLine + 1 + maxBytesPerLine + 1;
+
+ const uint8_t* cur = data.begin();
+ const uint8_t* end = data.end();
+
+ static char s_hex[] = "0123456789abcdef";
+
+ while (cur < end)
+ {
+ size_t count = size_t(end - cur);
+ count = (count > size_t(maxBytesPerLine)) ? size_t(maxBytesPerLine) : count;
+
+ char* startDst = writer->beginAppendBuffer(maxCharsPerLine);
+ char* dst = startDst;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ uint8_t byte = cur[i];
+ *dst++ = s_hex[byte >> 4];
+ *dst++ = s_hex[byte & 0xf];
+ }
+
+ *dst++ = ' ';
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ char c = char(cur[i]);
+
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 32 && (c & 0x80) == 0))
+ {
+ }
+ else
+ {
+ c = '.';
+ }
+ *dst++ = c;
+ }
+
+ *dst++ = '\n';
+ SLANG_ASSERT(dst <= startDst + maxCharsPerLine);
+
+ SLANG_RETURN_ON_FAIL(writer->endAppendBuffer(startDst, size_t(dst - startDst)));
+
+ cur += count;
+ }
+
+ return SLANG_OK;
+}
+
+static int _parseHexDigit(char c)
+{
+ if (c >= '0' && c <= '9')
+ {
+ return c -'0';
+ }
+ else if (c >= 'a' && c <= 'f')
+ {
+ return c - 'a' + 10;
+ }
+ else if (c >= 'A' && c <= 'F')
+ {
+ return c - 'A' + 10;
+ }
+ return -1;
+}
+
+/* static */SlangResult HexDumpUtil::parse(const UnownedStringSlice& lines, List<uint8_t>& outBytes)
+{
+ outBytes.clear();
+
+ bool inHex = false;
+
+ LineParser lineParser(lines);
+ for (const auto& line : lineParser)
+ {
+ if (!inHex)
+ {
+ if (line.startsWith(s_start))
+ {
+ inHex = true;
+ continue;
+ }
+ }
+ else
+ {
+ if (line.startsWith(s_end))
+ {
+ break;
+ }
+ }
+
+ const char* cur = line.begin();
+ const char* end = line.end();
+
+ while(cur + 2 <= end)
+ {
+ const char c = cur[0];
+ if (c == ' ' || c== '\n' || c == '\r' || c == '\t')
+ {
+ // Skip to next line
+ break;
+ }
+
+ const int hi = _parseHexDigit(c);
+ const int lo = _parseHexDigit(cur[1]);
+ cur += 2;
+
+ if (hi < 0 || lo < 0)
+ {
+ return SLANG_FAIL;
+ }
+ outBytes.add(uint8_t((hi << 4) | lo));
+ }
+ }
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult HexDumpUtil::parseWithMarkers(const UnownedStringSlice& lines, List<uint8_t>& outBytes)
+{
+ UnownedStringSlice remaining(lines), line;
+
+ while(StringUtil::extractLine(remaining, line))
+ {
+ if (line.startsWith(s_start))
+ {
+ // Extract next line
+ if (!StringUtil::extractLine(remaining, line))
+ {
+ return SLANG_FAIL;
+ }
+ // It's the start line
+ UnownedStringSlice startLine = line;
+
+ // Look for the ending line
+ do
+ {
+ if (line.startsWith(s_end))
+ {
+ return parse(UnownedStringSlice(startLine.begin(), line.begin()), outBytes);
+ }
+ }
+ while ( StringUtil::extractLine(remaining, line));
+ }
+ }
+
+ return SLANG_FAIL;
+}
+
+}