summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-03-18 17:30:33 -0700
committerGitHub <noreply@github.com>2019-03-18 17:30:33 -0700
commita2dd7c4feae3c4da3a1f8de90171795d12eb8879 (patch)
tree6149d980d99842952876518a59dc31df1b91eb39 /src
parent1cd0157985c7f09e81aee4fb79511888212559f2 (diff)
downloadbinaryen-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.cpp12
-rw-r--r--src/support/file.h2
-rw-r--r--src/wasm-io.h6
-rw-r--r--src/wasm/wasm-io.cpp46
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());
}