diff options
Diffstat (limited to 'tools/test-process')
| -rw-r--r-- | tools/test-process/test-process-main.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/tools/test-process/test-process-main.cpp b/tools/test-process/test-process-main.cpp new file mode 100644 index 000000000..c31fec3ed --- /dev/null +++ b/tools/test-process/test-process-main.cpp @@ -0,0 +1,193 @@ +// test-process-main.cpp + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +#include "../../slang-com-helper.h" + +#include "../../source/core/slang-string.h" +#include "../../source/core/slang-io.h" +#include "../../source/core/slang-string-util.h" +#include "../../source/core/slang-process-util.h" + +#include "../../source/core/slang-test-tool-util.h" +#include "../../source/core/slang-http.h" + +namespace TestProcess +{ +using namespace Slang; + +static void _makeStdStreamsUnbuffered() +{ + // Make these streams unbuffered + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); +} + +static SlangResult _outputCount(int argc, const char* const* argv) +{ + if (argc < 3) + { + return SLANG_FAIL; + } + // Get the count + const Index count = StringToInt(argv[2]); + + // If we want to crash + Index crashIndex = -1; + if (argc > 3) + { + // When we crash, we want to make sure everything is flushed... + _makeStdStreamsUnbuffered(); + crashIndex = StringToInt(argv[3]); + } + + FILE* fileOut = stdout; + + StringBuilder buf; + for (Index i = 0; i < count; ++i) + { + buf.Clear(); + buf << i << "\n"; + + fwrite(buf.getBuffer(), 1, buf.getLength(), fileOut); + + if (i == crashIndex) + { + // Use to simulate a crash. + SLANG_BREAKPOINT(0); + throw; + } + } + + // NOTE! There is no flush here, we want to see if everything works if we just stream out. + return SLANG_OK; +} + +static SlangResult _outputReflect() +{ + // Read lines from std input. + // When hit line with just 'end', terminate + + // Get in as Stream + + RefPtr<Stream> stdinStream; + Process::getStdStream(Process::StreamType::StdIn, stdinStream); + + FILE* fileOut = stdout; + + List<Byte> buffer; + + Index lineCount = 0; + Index startIndex = 0; + + while (true) + { + SLANG_RETURN_ON_FAIL(StreamUtil::read(stdinStream, 0, buffer)); + + while (true) + { + UnownedStringSlice slice((const char*)buffer.begin() + startIndex, (const char*)buffer.end()); + UnownedStringSlice line; + + if (!StringUtil::extractLine(slice, line) || slice.begin() == nullptr) + { + break; + } + + // Process the line + if (line == UnownedStringSlice::fromLiteral("end")) + { + return SLANG_OK; + } + + // Write the text to the output stream + fwrite(line.begin(), 1, line.getLength(), fileOut); + fputc('\n', fileOut); + + lineCount++; + + // Move the start index forward + const Index newStartIndex = slice.begin() ? Index(slice.begin() - (const char*)buffer.getBuffer()) : buffer.getCount(); + SLANG_ASSERT(newStartIndex > startIndex); + startIndex = newStartIndex; + } + } +} + +static SlangResult _httpReflect(int argc, const char* const* argv) +{ + SLANG_UNUSED(argc); + SLANG_UNUSED(argv); + + RefPtr<Stream> stdinStream, stdoutStream; + + Process::getStdStream(Process::StreamType::StdIn, stdinStream); + Process::getStdStream(Process::StreamType::StdOut, stdoutStream); + + RefPtr<BufferedReadStream> readStream(new BufferedReadStream(stdinStream)); + + RefPtr<HTTPPacketConnection> connection = new HTTPPacketConnection(readStream, stdoutStream); + + while (connection->isActive()) + { + // Block waiting for content (or error/closed) + SLANG_RETURN_ON_FAIL(connection->waitForResult()); + + // If we have content do something with it + if (connection->hasContent()) + { + auto content = connection->getContent(); + + // If it just holds 'end' then we are done + const UnownedStringSlice slice((const char*)content.begin(), content.getCount()); + + if (slice == UnownedStringSlice::fromLiteral("end")) + { + break; + } + + // Else reflect it back + SLANG_RETURN_ON_FAIL(connection->write(content.begin(), content.getCount())); + + // Consume that content/packet + connection->consumeContent(); + } + } + + return SLANG_OK; +} + +static SlangResult execute(int argc, const char*const* argv) +{ + if (argc < 2) + { + return SLANG_FAIL; + } + + // Get the tool name + const String toolName = argv[1]; + if (toolName == "reflect") + { + return _outputReflect(); + } + else if (toolName == "count") + { + return _outputCount(argc, argv); + } + else if (toolName == "http-reflect") + { + return _httpReflect(argc, argv); + } + return SLANG_E_NOT_AVAILABLE; +} + +} // namespace TestProcess + +int main(int argc, const char* const* argv) +{ + SlangResult res = TestProcess::execute(argc, argv); + return (int)Slang::TestToolUtil::getReturnCode(res); +} |
