diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2019-03-18 17:30:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-18 17:30:33 -0700 |
commit | a2dd7c4feae3c4da3a1f8de90171795d12eb8879 (patch) | |
tree | 6149d980d99842952876518a59dc31df1b91eb39 /src | |
parent | 1cd0157985c7f09e81aee4fb79511888212559f2 (diff) | |
download | binaryen-a2dd7c4feae3c4da3a1f8de90171795d12eb8879.tar.gz binaryen-a2dd7c4feae3c4da3a1f8de90171795d12eb8879.tar.bz2 binaryen-a2dd7c4feae3c4da3a1f8de90171795d12eb8879.zip |
Allow tools to read from stdin (#1950)
This is necessary to write tests that don't require temporary files,
such as in #1948, and is generally useful.
Diffstat (limited to 'src')
-rw-r--r-- | src/support/file.cpp | 12 | ||||
-rw-r--r-- | src/support/file.h | 2 | ||||
-rw-r--r-- | src/wasm-io.h | 6 | ||||
-rw-r--r-- | src/wasm/wasm-io.cpp | 46 |
4 files changed, 57 insertions, 9 deletions
diff --git a/src/support/file.cpp b/src/support/file.cpp index 19401b21d..2fe636cfd 100644 --- a/src/support/file.cpp +++ b/src/support/file.cpp @@ -21,6 +21,17 @@ #include <cstdint> #include <limits> +std::vector<char> wasm::read_stdin(Flags::DebugOption debug) { + if (debug == Flags::Debug) std::cerr << "Loading stdin..." << std::endl; + std::vector<char> input; + char c; + while (std::cin.get(c) && !std::cin.eof()) { + input.push_back(c); + } + return input; +} + + template<typename T> T wasm::read_file(const std::string& filename, Flags::BinaryOption binary, Flags::DebugOption debug) { if (debug == Flags::Debug) std::cerr << "Loading '" << filename << "'..." << std::endl; @@ -84,4 +95,3 @@ size_t wasm::file_size(std::string filename) { std::ifstream infile(filename, std::ifstream::ate | std::ifstream::binary); return infile.tellg(); } - diff --git a/src/support/file.h b/src/support/file.h index e94d23fad..cb9c82ca9 100644 --- a/src/support/file.h +++ b/src/support/file.h @@ -39,6 +39,8 @@ namespace Flags { }; } +std::vector<char> read_stdin(Flags::DebugOption); + template<typename T> T read_file(const std::string& filename, Flags::BinaryOption binary, Flags::DebugOption debug); // Declare the valid explicit specializations. diff --git a/src/wasm-io.h b/src/wasm-io.h index 2dfdbae6c..6d8dcc6e5 100644 --- a/src/wasm-io.h +++ b/src/wasm-io.h @@ -42,11 +42,15 @@ public: // read binary void readBinary(std::string filename, Module& wasm, std::string sourceMapFilename=""); - // read text or binary, checking the contents for what it is + // read text or binary, checking the contents for what it is. If `filename` is + // empty, read from stdin. void read(std::string filename, Module& wasm, std::string sourceMapFilename=""); // check whether a file is a wasm binary bool isBinaryFile(std::string filename); + +private: + void readStdin(Module& wasm, std::string sourceMapFilename); }; class ModuleWriter : public ModuleIO { diff --git a/src/wasm/wasm-io.cpp b/src/wasm/wasm-io.cpp index 95ffe6e89..057798d2e 100644 --- a/src/wasm/wasm-io.cpp +++ b/src/wasm/wasm-io.cpp @@ -30,18 +30,21 @@ namespace wasm { -void ModuleReader::readText(std::string filename, Module& wasm) { - if (debug) std::cerr << "reading text from " << filename << "\n"; - auto input(read_file<std::string>(filename, Flags::Text, debug ? Flags::Debug : Flags::Release)); +static void readTextData(std::string& input, Module& wasm) { SExpressionParser parser(const_cast<char*>(input.c_str())); Element& root = *parser.root; SExpressionWasmBuilder builder(wasm, *root[0]); + } -void ModuleReader::readBinary(std::string filename, Module& wasm, - std::string sourceMapFilename) { - if (debug) std::cerr << "reading binary from " << filename << "\n"; - auto input(read_file<std::vector<char>>(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release)); +void ModuleReader::readText(std::string filename, Module& wasm) { + if (debug) std::cerr << "reading text from " << filename << "\n"; + auto input(read_file<std::string>(filename, Flags::Text, debug ? Flags::Debug : Flags::Release)); + readTextData(input, wasm); +} + +static void readBinaryData(std::vector<char>& input, Module& wasm, + std::string sourceMapFilename, bool debug) { std::unique_ptr<std::ifstream> sourceMapStream; WasmBinaryBuilder parser(wasm, input, debug); if (sourceMapFilename.size()) { @@ -55,6 +58,13 @@ void ModuleReader::readBinary(std::string filename, Module& wasm, } } +void ModuleReader::readBinary(std::string filename, Module& wasm, + std::string sourceMapFilename) { + if (debug) std::cerr << "reading binary from " << filename << "\n"; + auto input(read_file<std::vector<char>>(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release)); + readBinaryData(input, wasm, sourceMapFilename, debug); +} + bool ModuleReader::isBinaryFile(std::string filename) { std::ifstream infile; std::ios_base::openmode flags = std::ifstream::in | std::ifstream::binary; @@ -67,6 +77,11 @@ bool ModuleReader::isBinaryFile(std::string filename) { void ModuleReader::read(std::string filename, Module& wasm, std::string sourceMapFilename) { + // empty filename means read from stdin + if (!filename.size()) { + readStdin(wasm, sourceMapFilename); + return; + } if (isBinaryFile(filename)) { readBinary(filename, wasm, sourceMapFilename); } else { @@ -78,6 +93,23 @@ void ModuleReader::read(std::string filename, Module& wasm, } } +// TODO: reading into a vector<char> then copying into a string is unnecessarily +// inefficient. It would be better to read just once into a stringstream. +void ModuleReader::readStdin(Module& wasm, std::string sourceMapFilename) { + std::vector<char> input = read_stdin(debug ? Flags::Debug : Flags::Release); + if (input.size() >= 4 && input[0] == '\0' && input[1] == 'a' && + input[2] == 's' && input[3] == 'm') { + readBinaryData(input, wasm, sourceMapFilename, debug); + } else { + std::ostringstream s; + s.write(input.data(), input.size()); + s << '\0'; + std::string input_str = s.str(); + readTextData(input_str, wasm); + } +} + + void ModuleWriter::writeText(Module& wasm, Output& output) { WasmPrinter::printModule(&wasm, output.getStream()); } |