diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/s2wasm-main.cpp | 115 | ||||
-rw-r--r-- | src/s2wasm.h | 22 | ||||
-rw-r--r-- | src/wasm.h | 2 |
3 files changed, 100 insertions, 39 deletions
diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp index 247974fee..7e5b99057 100644 --- a/src/s2wasm-main.cpp +++ b/src/s2wasm-main.cpp @@ -24,40 +24,99 @@ using namespace cashew; using namespace wasm; namespace wasm { -int debug = 0; +struct Options { + bool debug; + std::string infile; + std::string outfile; + Options() : debug(false) {} +}; + +bool optionIs(const char *arg, const char *LongOpt, const char *ShortOpt) { + return strcmp(arg, LongOpt) == 0 || strcmp(arg, ShortOpt) == 0; +} + +void processCommandLine(int argc, const char *argv[], Options *options) { + for (size_t i = 1; i != argc; ++i) { + if (optionIs(argv[i], "--help", "-h")) { + std::cerr << "s2wasm INFILE\n\n" + "Link .s file into .wast\n\n" + "Optional arguments:\n" + " -n, --help Show this help message and exit\n" + " -d, --debug Print debug information to stderr\n" + " -o, --output Output file (stdout if not specified)\n" + << std::endl; + exit(EXIT_SUCCESS); + } else if (optionIs(argv[i], "--debug", "-d")) { + options->debug = true; + } else if (optionIs(argv[i], "--output", "-o")) { + if (i + 1 == argc) { + std::cerr << "No output file" << std::endl; + exit(EXIT_FAILURE); + } + if (options->outfile.size()) { + std::cerr << "Expected only one output file, got '" << options->outfile + << "' and '" << argv[i] << "'" << std::endl; + exit(EXIT_FAILURE); + } + options->outfile = argv[++i]; + } else { + if (options->infile.size()) { + std::cerr << "Expected only one input file, got '" << options->infile + << "' and '" << argv[i] << "'" << std::endl; + exit(EXIT_FAILURE); + } + options->infile = argv[i]; + } + } } -int main(int argc, char **argv) { - debug = getenv("S2WASM_DEBUG") ? getenv("S2WASM_DEBUG")[0] - '0' : 0; - - char *infile = argv[1]; - - if (debug) std::cerr << "loading '" << infile << "'...\n"; - FILE *f = fopen(argv[1], "r"); - assert(f); - fseek(f, 0, SEEK_END); - int size = ftell(f); - char *input = new char[size+1]; - rewind(f); - int num = fread(input, 1, size, f); - // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when - // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one), - // so return value of fread can be less than size reported by ftell, and that is normal. - assert((num > 0 || size == 0) && num <= size); - fclose(f); - input[num] = 0; - - if (debug) std::cerr << "parsing and wasming...\n"; +} // namespace wasm + +int main(int argc, const char *argv[]) { + Options options; + processCommandLine(argc, argv, &options); + + std::string input; + { + if (options.debug) + std::cerr << "Loading '" << options.infile << "'..." << std::endl; + std::ifstream infile(options.infile); + if (!infile.is_open()) { + std::cerr << "Failed opening '" << options.infile << "'" << std::endl; + exit(EXIT_FAILURE); + } + infile.seekg(0, std::ios::end); + size_t insize = infile.tellg(); + input.resize(insize + 1); + infile.seekg(0); + infile.read(&input[0], insize); + } + + std::streambuf *buffer; + std::ofstream outfile; + if (options.outfile.size()) { + if (options.debug) std::cerr << "Opening '" << options.outfile << std::endl; + outfile.open(options.outfile, std::ofstream::out | std::ofstream::trunc); + if (!outfile.is_open()) { + std::cerr << "Failed opening '" << options.outfile << "'" << std::endl; + exit(EXIT_FAILURE); + } + buffer = outfile.rdbuf(); + } else { + buffer = std::cout.rdbuf(); + } + std::ostream out(buffer); + + if (options.debug) std::cerr << "Parsing and wasming..." << std::endl; AllocatingModule wasm; - S2WasmBuilder s2wasm(wasm, input); + S2WasmBuilder s2wasm(wasm, input.c_str(), options.debug); - if (debug) std::cerr << "emscripten gluing...\n"; + if (options.debug) std::cerr << "Emscripten gluing..." << std::endl; std::stringstream meta; s2wasm.emscriptenGlue(meta); - if (debug) std::cerr << "printing...\n"; - std::cout << wasm; - std::cout << meta.str(); + if (options.debug) std::cerr << "Printing..." << std::endl; + out << wasm << meta.str() << std::endl; - if (debug) std::cerr << "done.\n"; + if (options.debug) std::cerr << "Done." << std::endl; } diff --git a/src/s2wasm.h b/src/s2wasm.h index fea5f04a8..5801f2620 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -24,8 +24,6 @@ namespace wasm { -extern int debug; // wasm::debug is set in main(), typically from an env var - cashew::IString EMSCRIPTEN_ASM_CONST("emscripten_asm_const"); // @@ -35,15 +33,17 @@ cashew::IString EMSCRIPTEN_ASM_CONST("emscripten_asm_const"); class S2WasmBuilder { AllocatingModule& wasm; MixedArena& allocator; - char *s; + const char *s; + bool debug; public: - S2WasmBuilder(AllocatingModule& wasm, char *input) : wasm(wasm), allocator(wasm.allocator) { - s = input; - scan(); - s = input; - process(); - fix(); + S2WasmBuilder(AllocatingModule& wasm, const char* input, bool debug) + : wasm(wasm), allocator(wasm.allocator), debug(debug) { + s = input; + scan(); + s = input; + process(); + fix(); } private: @@ -217,7 +217,7 @@ private: skipWhitespace(); if (*s != '$') return Name(); std::string str; - char *before = s; + const char *before = s; while (*s && *s != '=' && *s != '\n' && *s != ',') { str += *s; s++; @@ -393,7 +393,7 @@ private: }; auto getNumInputs = [&]() { int ret = 1; - char *t = s; + const char *t = s; while (*t != '\n') { if (*t == ',') ret++; t++; diff --git a/src/wasm.h b/src/wasm.h index d51b1ea4d..8583f9492 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -47,6 +47,8 @@ #include <cassert> #include <cstddef> #include <cstdint> +#include <cstring> +#include <fstream> #include <map> #include <vector> |