Skip to content
Next Next commit
Use std::filesystem::path instead of string for file paths
  • Loading branch information
dschuff committed Apr 5, 2023
commit 63f61da7dfd7a0511b9ccd214943ff846b459191
19 changes: 7 additions & 12 deletions src/support/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <limits>

Expand Down Expand Up @@ -47,7 +48,7 @@ template<> std::string do_read_stdin<std::string>::operator()() {
}

template<typename T>
T wasm::read_file(const std::string& filename, Flags::BinaryOption binary) {
T wasm::read_file(const std::filesystem::path& filename, Flags::BinaryOption binary) {
if (filename == "-") {
return do_read_stdin<T>{}();
}
Expand Down Expand Up @@ -95,11 +96,11 @@ std::string wasm::read_possible_response_file(const std::string& input) {
}

// Explicit instantiations for the explicit specializations.
template std::string wasm::read_file<>(const std::string&, Flags::BinaryOption);
template std::vector<char> wasm::read_file<>(const std::string&,
template std::string wasm::read_file<>(const std::filesystem::path&, Flags::BinaryOption);
template std::vector<char> wasm::read_file<>(const std::filesystem::path&,
Flags::BinaryOption);

wasm::Output::Output(const std::string& filename, Flags::BinaryOption binary)
wasm::Output::Output(const std::filesystem::path& filename, Flags::BinaryOption binary)
: outfile(), out([this, filename, binary]() {
// Ensure a single return at the very end, to avoid clang-tidy warnings
// about the types of different returns here.
Expand All @@ -121,13 +122,7 @@ wasm::Output::Output(const std::string& filename, Flags::BinaryOption binary)
return buffer;
}()) {}

void wasm::copy_file(std::string input, std::string output) {
std::ifstream src(input, std::ios::binary);
std::ofstream dst(output, std::ios::binary);
dst << src.rdbuf();
void wasm::copy_file(std::filesystem::path input, std::filesystem::path output) {
std::filesystem::copy_file(input, output, std::filesystem::copy_options::overwrite_existing);
}

size_t wasm::file_size(std::string filename) {
std::ifstream infile(filename, std::ifstream::ate | std::ifstream::binary);
return infile.tellg();
}
15 changes: 7 additions & 8 deletions src/support/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef wasm_support_file_h
#define wasm_support_file_h

#include <filesystem>
#include <fstream>
#include <string>
#include <utility>
Expand All @@ -35,12 +36,12 @@ enum BinaryOption { Binary, Text };
std::vector<char> read_stdin();

template<typename T>
T read_file(const std::string& filename, Flags::BinaryOption binary);
T read_file(const std::filesystem::path& filename, Flags::BinaryOption binary);

// Declare the valid explicit specializations.
extern template std::string read_file<>(const std::string&,
extern template std::string read_file<>(const std::filesystem::path&,
Flags::BinaryOption);
extern template std::vector<char> read_file<>(const std::string&,
extern template std::vector<char> read_file<>(const std::filesystem::path&,
Flags::BinaryOption);

// Given a string which may be a response file (i.e., a filename starting
Expand All @@ -51,7 +52,7 @@ std::string read_possible_response_file(const std::string&);
class Output {
public:
// An empty filename or "-" will open stdout instead.
Output(const std::string& filename, Flags::BinaryOption binary);
Output(const std::filesystem::path& filename, Flags::BinaryOption binary);
~Output() = default;
template<typename T> std::ostream& operator<<(const T& v) { return out << v; }

Expand All @@ -69,11 +70,9 @@ class Output {
std::ostream out;
};

// Copies a file to another file
void copy_file(std::string input, std::string output);
// Copies a file to another file, overwriting if the fiel exists
void copy_file(std::filesystem::path input, std::filesystem::path output);

// Retusn the size of a file
size_t file_size(std::string filename);

} // namespace wasm

Expand Down
2 changes: 2 additions & 0 deletions src/tools/wasm-reduce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <memory>

#include "ir/branch-utils.h"
Expand Down Expand Up @@ -71,6 +72,7 @@ std::string GetLastErrorStdStr() {
return std::string();
}
#endif
using std::filesystem::file_size;
using namespace wasm;

// A timeout on every execution of the command.
Expand Down
30 changes: 15 additions & 15 deletions src/wasm-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ class ModuleReader : public ModuleIOBase {
}

// read text
void readText(std::string filename, Module& wasm);
void readText(std::filesystem::path filename, Module& wasm);
// read binary
void readBinary(std::string filename,
void readBinary(std::filesystem::path filename,
Module& wasm,
std::string sourceMapFilename = "");
std::filesystem::path sourceMapFilename = "");
// 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 = "");
read(std::filesystem::path filename, Module& wasm, std::filesystem::path sourceMapFilename = "");
// check whether a file is a wasm binary
bool isBinaryFile(std::string filename);
bool isBinaryFile(std::filesystem::path filename);

private:
bool DWARF = false;
Expand All @@ -77,11 +77,11 @@ class ModuleReader : public ModuleIOBase {

bool skipFunctionBodies = false;

void readStdin(Module& wasm, std::string sourceMapFilename);
void readStdin(Module& wasm, std::filesystem::path sourceMapFilename);

void readBinaryData(std::vector<char>& input,
Module& wasm,
std::string sourceMapFilename);
std::filesystem::path sourceMapFilename);
};

class ModuleWriter : public ModuleIOBase {
Expand All @@ -90,18 +90,18 @@ class ModuleWriter : public ModuleIOBase {
// TODO: Remove `emitModuleName`. See the comment in wasm-binary.h
bool emitModuleName = false;

std::string symbolMap;
std::string sourceMapFilename;
std::string sourceMapUrl;
std::filesystem::path symbolMap;
std::filesystem::path sourceMapFilename;
std::filesystem::path sourceMapUrl;

public:
// Writing defaults to not storing the names section. Storing it is a user-
// observable fact that must be opted into.
ModuleWriter() { setDebugInfo(false); }

void setBinary(bool binary_) { binary = binary_; }
void setSymbolMap(std::string symbolMap_) { symbolMap = symbolMap_; }
void setSourceMapFilename(std::string sourceMapFilename_) {
void setSymbolMap(std::filesystem::path symbolMap_) { symbolMap = symbolMap_; }
void setSourceMapFilename(std::filesystem::path sourceMapFilename_) {
sourceMapFilename = sourceMapFilename_;
}
void setSourceMapUrl(std::string sourceMapUrl_) {
Expand All @@ -111,15 +111,15 @@ class ModuleWriter : public ModuleIOBase {

// write text
void writeText(Module& wasm, Output& output);
void writeText(Module& wasm, std::string filename);
void writeText(Module& wasm, std::filesystem::path filename);
// write binary
void writeBinary(Module& wasm, Output& output);
void writeBinary(Module& wasm, std::string filename);
void writeBinary(Module& wasm, std::filesystem::path filename);
// write text or binary, defaulting to binary unless setBinary(false),
// and unless there is no output file (in which case we write text
// to stdout).
void write(Module& wasm, Output& output);
void write(Module& wasm, std::string filename);
void write(Module& wasm, std::filesystem::path filename);
};

} // namespace wasm
Expand Down
34 changes: 17 additions & 17 deletions src/wasm/wasm-io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,23 @@ static void readTextData(std::string& input, Module& wasm, IRProfile profile) {
}
}

void ModuleReader::readText(std::string filename, Module& wasm) {
void ModuleReader::readText(std::filesystem::path filename, Module& wasm) {
BYN_TRACE("reading text from " << filename << "\n");
auto input(read_file<std::string>(filename, Flags::Text));
readTextData(input, wasm, profile);
}

void ModuleReader::readBinaryData(std::vector<char>& input,
Module& wasm,
std::string sourceMapFilename) {
std::filesystem::path sourceMapFilename) {
std::unique_ptr<std::ifstream> sourceMapStream;
// Assume that the wasm has had its initial features applied, and use those
// while parsing.
WasmBinaryBuilder parser(wasm, wasm.features, input);
parser.setDebugInfo(debugInfo);
parser.setDWARF(DWARF);
parser.setSkipFunctionBodies(skipFunctionBodies);
if (sourceMapFilename.size()) {
if (!sourceMapFilename.empty()) {
sourceMapStream = std::make_unique<std::ifstream>();
sourceMapStream->open(sourceMapFilename);
parser.setDebugLocations(sourceMapStream.get());
Expand All @@ -78,15 +78,15 @@ void ModuleReader::readBinaryData(std::vector<char>& input,
}
}

void ModuleReader::readBinary(std::string filename,
void ModuleReader::readBinary(std::filesystem::path filename,
Module& wasm,
std::string sourceMapFilename) {
std::filesystem::path sourceMapFilename) {
BYN_TRACE("reading binary from " << filename << "\n");
auto input(read_file<std::vector<char>>(filename, Flags::Binary));
readBinaryData(input, wasm, sourceMapFilename);
}

bool ModuleReader::isBinaryFile(std::string filename) {
bool ModuleReader::isBinaryFile(std::filesystem::path filename) {
std::ifstream infile;
std::ios_base::openmode flags = std::ifstream::in | std::ifstream::binary;
infile.open(filename, flags);
Expand All @@ -97,19 +97,19 @@ bool ModuleReader::isBinaryFile(std::string filename) {
buffer[3] == 'm';
}

void ModuleReader::read(std::string filename,
void ModuleReader::read(std::filesystem::path filename,
Module& wasm,
std::string sourceMapFilename) {
std::filesystem::path sourceMapFilename) {
// empty filename or "-" means read from stdin
if (!filename.size() || filename == "-") {
if (filename.empty() || filename == "-") {
readStdin(wasm, sourceMapFilename);
return;
}
if (isBinaryFile(filename)) {
readBinary(filename, wasm, sourceMapFilename);
} else {
// default to text
if (sourceMapFilename.size()) {
if (!sourceMapFilename.empty()) {
std::cerr << "Binaryen ModuleReader::read() - source map filename "
"provided, but file appears to not be binary\n";
}
Expand All @@ -119,7 +119,7 @@ void ModuleReader::read(std::string filename,

// 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) {
void ModuleReader::readStdin(Module& wasm, std::filesystem::path sourceMapFilename) {
std::vector<char> input = read_stdin();
if (input.size() >= 4 && input[0] == '\0' && input[1] == 'a' &&
input[2] == 's' && input[3] == 'm') {
Expand All @@ -140,7 +140,7 @@ void ModuleWriter::writeText(Module& wasm, Output& output) {
output.getStream() << wasm;
}

void ModuleWriter::writeText(Module& wasm, std::string filename) {
void ModuleWriter::writeText(Module& wasm, std::filesystem::path filename) {
BYN_TRACE("writing text to " << filename << "\n");
Output output(filename, Flags::Text);
writeText(wasm, output);
Expand All @@ -155,12 +155,12 @@ void ModuleWriter::writeBinary(Module& wasm, Output& output) {
writer.setEmitModuleName(true);
}
std::unique_ptr<std::ofstream> sourceMapStream;
if (sourceMapFilename.size()) {
if (!sourceMapFilename.empty()) {
sourceMapStream = std::make_unique<std::ofstream>();
sourceMapStream->open(sourceMapFilename);
writer.setSourceMap(sourceMapStream.get(), sourceMapUrl);
}
if (symbolMap.size() > 0) {
if (!symbolMap.empty()) {
writer.setSymbolMap(symbolMap);
}
writer.write();
Expand All @@ -170,7 +170,7 @@ void ModuleWriter::writeBinary(Module& wasm, Output& output) {
}
}

void ModuleWriter::writeBinary(Module& wasm, std::string filename) {
void ModuleWriter::writeBinary(Module& wasm, std::filesystem::path filename) {
BYN_TRACE("writing binary to " << filename << "\n");
Output output(filename, Flags::Binary);
writeBinary(wasm, output);
Expand All @@ -184,8 +184,8 @@ void ModuleWriter::write(Module& wasm, Output& output) {
}
}

void ModuleWriter::write(Module& wasm, std::string filename) {
if (binary && filename.size() > 0) {
void ModuleWriter::write(Module& wasm, std::filesystem::path filename) {
if (binary && !filename.empty()) {
writeBinary(wasm, filename);
} else {
writeText(wasm, filename);
Expand Down