diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-07-17 10:26:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-17 10:26:37 -0400 |
| commit | 749634a2a6e03acf435c39f78b933a01b90a7440 (patch) | |
| tree | 950203d3fc29610428b0ca03eb756911b9b11f47 /source/core/slang-hex-dump-util.cpp | |
| parent | f52f5cd4a7b5b71617b949fc62a78abe8c4822b3 (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.cpp | 183 |
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; +} + +} |
