tools: Move io utils to cpp (#5869)

In preparation for more code in that file, which would get unwieldy in a
header.
This commit is contained in:
Shahbaz Youssefi 2024-10-28 13:31:54 -04:00 committed by GitHub
parent ce92630396
commit 5f1e86cb55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 229 additions and 173 deletions

View File

@ -269,6 +269,7 @@ cc_library(
cc_library( cc_library(
name = "tools_io", name = "tools_io",
hdrs = ["tools/io.h"], hdrs = ["tools/io.h"],
srcs = ["tools/io.cpp"],
copts = COMMON_COPTS, copts = COMMON_COPTS,
) )

View File

@ -1466,6 +1466,15 @@ source_set("spvtools_tools_util") {
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
} }
source_set("spvtools_tools_io") {
sources = [
"tools/io.cpp",
"tools/io.h",
]
deps = [ ":spvtools_headers" ]
configs += [ ":spvtools_internal_config" ]
}
if (spvtools_build_executables) { if (spvtools_build_executables) {
executable("spirv-as") { executable("spirv-as") {
sources = [ "tools/as/as.cpp" ] sources = [ "tools/as/as.cpp" ]
@ -1473,6 +1482,7 @@ if (spvtools_build_executables) {
":spvtools", ":spvtools",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
} }
@ -1483,6 +1493,7 @@ if (spvtools_build_executables) {
":spvtools", ":spvtools",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
} }
@ -1493,6 +1504,7 @@ if (spvtools_build_executables) {
":spvtools", ":spvtools",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
":spvtools_val", ":spvtools_val",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
@ -1508,6 +1520,7 @@ if (spvtools_build_executables) {
":spvtools", ":spvtools",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
} }
@ -1519,6 +1532,7 @@ if (spvtools_build_executables) {
":spvtools_opt", ":spvtools_opt",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
":spvtools_val", ":spvtools_val",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
@ -1532,6 +1546,7 @@ if (spvtools_build_executables) {
":spvtools_opt", ":spvtools_opt",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
":spvtools_val", ":spvtools_val",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]
@ -1552,6 +1567,7 @@ if (!is_ios && !spirv_is_winuwp && build_with_chromium && spvtools_build_executa
":spvtools_reduce", ":spvtools_reduce",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
":spvtools_val", ":spvtools_val",
"//third_party/protobuf:protobuf_full", "//third_party/protobuf:protobuf_full",
] ]
@ -1571,6 +1587,7 @@ if (!is_ios && !spirv_is_winuwp && spvtools_build_executables) {
":spvtools_reduce", ":spvtools_reduce",
":spvtools_software_version", ":spvtools_software_version",
":spvtools_tools_util", ":spvtools_tools_util",
":spvtools_tools_io",
":spvtools_val", ":spvtools_val",
] ]
configs += [ ":spvtools_internal_config" ] configs += [ ":spvtools_internal_config" ]

View File

@ -123,7 +123,8 @@ if (${SPIRV_BUILD_FUZZER})
transformation_wrap_early_terminator_in_function_test.cpp transformation_wrap_early_terminator_in_function_test.cpp
transformation_wrap_region_in_selection_test.cpp transformation_wrap_region_in_selection_test.cpp
transformation_wrap_vector_synonym_test.cpp transformation_wrap_vector_synonym_test.cpp
uniform_buffer_element_descriptor_test.cpp) uniform_buffer_element_descriptor_test.cpp
${spirv-tools_SOURCE_DIR}/tools/io.cpp)
if (${SPIRV_ENABLE_LONG_FUZZER_TESTS}) if (${SPIRV_ENABLE_LONG_FUZZER_TESTS})
# These are long-running tests that depend on random seeds. We do not want # These are long-running tests that depend on random seeds. We do not want

View File

@ -31,6 +31,7 @@ add_spvtools_unittest(TARGET reduce
structured_construct_to_block_test.cpp structured_construct_to_block_test.cpp
structured_loop_to_selection_test.cpp structured_loop_to_selection_test.cpp
validation_during_reduction_test.cpp validation_during_reduction_test.cpp
${spirv-tools_SOURCE_DIR}/tools/io.cpp
LIBS SPIRV-Tools-reduce LIBS SPIRV-Tools-reduce
) )

View File

@ -42,17 +42,18 @@ endfunction()
set(COMMON_TOOLS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/util/flags.cpp") set(COMMON_TOOLS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/util/flags.cpp")
if (NOT ${SPIRV_SKIP_EXECUTABLES}) if (NOT ${SPIRV_SKIP_EXECUTABLES})
add_spvtools_tool(TARGET spirv-diff SRCS ${COMMON_TOOLS_SRCS} diff/diff.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-diff SRCS ${COMMON_TOOLS_SRCS} diff/diff.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.cpp io.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-val SRCS ${COMMON_TOOLS_SRCS} val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-val SRCS ${COMMON_TOOLS_SRCS} val/val.cpp util/cli_consumer.cpp io.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-opt SRCS ${COMMON_TOOLS_SRCS} opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-opt SRCS ${COMMON_TOOLS_SRCS} opt/opt.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")) # iOS does not allow std::system calls which spirv-reduce requires if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")) # iOS does not allow std::system calls which spirv-reduce requires
add_spvtools_tool(TARGET spirv-reduce SRCS ${COMMON_TOOLS_SRCS} reduce/reduce.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-reduce SRCS ${COMMON_TOOLS_SRCS} reduce/reduce.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY})
endif() endif()
add_spvtools_tool(TARGET spirv-link SRCS ${COMMON_TOOLS_SRCS} link/linker.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-link SRCS ${COMMON_TOOLS_SRCS} link/linker.cpp io.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-lint SRCS ${COMMON_TOOLS_SRCS} lint/lint.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-lint SRCS ${COMMON_TOOLS_SRCS} lint/lint.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-as add_spvtools_tool(TARGET spirv-as
SRCS as/as.cpp SRCS as/as.cpp
io.cpp
${COMMON_TOOLS_SRCS} ${COMMON_TOOLS_SRCS}
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
target_include_directories(spirv-as PRIVATE ${spirv-tools_SOURCE_DIR} target_include_directories(spirv-as PRIVATE ${spirv-tools_SOURCE_DIR}
@ -61,6 +62,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
SRCS cfg/cfg.cpp SRCS cfg/cfg.cpp
cfg/bin_to_dot.h cfg/bin_to_dot.h
cfg/bin_to_dot.cpp cfg/bin_to_dot.cpp
io.cpp
${COMMON_TOOLS_SRCS} ${COMMON_TOOLS_SRCS}
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR} target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR}
@ -73,6 +75,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
SRCS objdump/objdump.cpp SRCS objdump/objdump.cpp
objdump/extract_source.cpp objdump/extract_source.cpp
util/cli_consumer.cpp util/cli_consumer.cpp
io.cpp
${COMMON_TOOLS_SRCS} ${COMMON_TOOLS_SRCS}
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
target_include_directories(spirv-objdump PRIVATE ${spirv-tools_SOURCE_DIR} target_include_directories(spirv-objdump PRIVATE ${spirv-tools_SOURCE_DIR}
@ -85,7 +88,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
endif() endif()
if(SPIRV_BUILD_FUZZER) if(SPIRV_BUILD_FUZZER)
add_spvtools_tool(TARGET spirv-fuzz SRCS fuzz/fuzz.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-fuzz ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-fuzz SRCS fuzz/fuzz.cpp util/cli_consumer.cpp io.cpp LIBS SPIRV-Tools-fuzz ${SPIRV_TOOLS_FULL_VISIBILITY})
set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-fuzz) set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-fuzz)
endif(SPIRV_BUILD_FUZZER) endif(SPIRV_BUILD_FUZZER)

View File

@ -106,7 +106,7 @@ int main(int, const char** argv) {
std::string inFile = flags::positional_arguments[0]; std::string inFile = flags::positional_arguments[0];
std::vector<char> contents; std::vector<char> contents;
if (!ReadTextFile<char>(inFile.c_str(), &contents)) return 1; if (!ReadTextFile(inFile.c_str(), &contents)) return 1;
spv_binary binary; spv_binary binary;
spv_diagnostic diagnostic = nullptr; spv_diagnostic diagnostic = nullptr;

View File

@ -75,7 +75,7 @@ int main(int, const char** argv) {
// Read the input binary. // Read the input binary.
std::vector<uint32_t> contents; std::vector<uint32_t> contents;
if (!ReadBinaryFile<uint32_t>(inFile.c_str(), &contents)) return 1; if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1;
spv_context context = spvContextCreate(kDefaultEnvironment); spv_context context = spvContextCreate(kDefaultEnvironment);
spv_diagnostic diagnostic = nullptr; spv_diagnostic diagnostic = nullptr;

View File

@ -82,7 +82,7 @@ bool is_assembly(const char* path) {
std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) { std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
if (is_assembly(path)) { if (is_assembly(path)) {
std::vector<char> contents; std::vector<char> contents;
if (!ReadTextFile<char>(path, &contents)) return {}; if (!ReadTextFile(path, &contents)) return {};
return spvtools::BuildModule( return spvtools::BuildModule(
kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, kDefaultEnvironment, spvtools::utils::CLIMessageConsumer,
@ -92,7 +92,7 @@ std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
} }
std::vector<uint32_t> contents; std::vector<uint32_t> contents;
if (!ReadBinaryFile<uint32_t>(path, &contents)) return {}; if (!ReadBinaryFile(path, &contents)) return {};
return spvtools::BuildModule(kDefaultEnvironment, return spvtools::BuildModule(kDefaultEnvironment,
spvtools::utils::CLIMessageConsumer, spvtools::utils::CLIMessageConsumer,

View File

@ -153,7 +153,7 @@ int main(int, const char** argv) {
// Read the input binary. // Read the input binary.
std::vector<uint32_t> contents; std::vector<uint32_t> contents;
if (!ReadBinaryFile<uint32_t>(inFile.c_str(), &contents)) return 1; if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1;
// If printing to standard output, then spvBinaryToText should // If printing to standard output, then spvBinaryToText should
// do the printing. In particular, colour printing on Windows is // do the printing. In particular, colour printing on Windows is

View File

@ -584,8 +584,7 @@ bool Fuzz(const spv_target_env& target_env,
[donor_filename, message_consumer, [donor_filename, message_consumer,
target_env]() -> std::unique_ptr<spvtools::opt::IRContext> { target_env]() -> std::unique_ptr<spvtools::opt::IRContext> {
std::vector<uint32_t> donor_binary; std::vector<uint32_t> donor_binary;
if (!ReadBinaryFile<uint32_t>(donor_filename.c_str(), if (!ReadBinaryFile(donor_filename.c_str(), &donor_binary)) {
&donor_binary)) {
return nullptr; return nullptr;
} }
return spvtools::BuildModule(target_env, message_consumer, return spvtools::BuildModule(target_env, message_consumer,
@ -712,7 +711,7 @@ int main(int argc, const char** argv) {
} }
std::vector<uint32_t> binary_in; std::vector<uint32_t> binary_in;
if (!ReadBinaryFile<uint32_t>(in_binary_file.c_str(), &binary_in)) { if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) {
return 1; return 1;
} }

175
tools/io.cpp Normal file
View File

@ -0,0 +1,175 @@
// Copyright (c) 2024 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "io.h"
#include <assert.h>
#if defined(SPIRV_WINDOWS)
#include <fcntl.h>
#include <io.h>
#define SET_STDIN_TO_BINARY_MODE() _setmode(_fileno(stdin), O_BINARY);
#define SET_STDIN_TO_TEXT_MODE() _setmode(_fileno(stdin), O_TEXT);
#define SET_STDOUT_TO_BINARY_MODE() _setmode(_fileno(stdout), O_BINARY);
#define SET_STDOUT_TO_TEXT_MODE() _setmode(_fileno(stdout), O_TEXT);
#define SET_STDOUT_MODE(mode) _setmode(_fileno(stdout), mode);
#else
#define SET_STDIN_TO_BINARY_MODE()
#define SET_STDIN_TO_TEXT_MODE()
#define SET_STDOUT_TO_BINARY_MODE() 0
#define SET_STDOUT_TO_TEXT_MODE() 0
#define SET_STDOUT_MODE(mode)
#endif
namespace {
// Appends the contents of the |file| to |data|, assuming each element in the
// file is of type |T|.
template <typename T>
void ReadFile(FILE* file, std::vector<T>* data) {
if (file == nullptr) return;
const int buf_size = 1024;
T buf[buf_size];
while (size_t len = fread(buf, sizeof(T), buf_size, file)) {
data->insert(data->end(), buf, buf + len);
}
}
// Returns true if |file| has encountered an error opening the file or reading
// the file as a series of element of type |T|. If there was an error, writes an
// error message to standard error.
template <class T>
bool WasFileCorrectlyRead(FILE* file, const char* filename) {
if (file == nullptr) {
fprintf(stderr, "error: file does not exist '%s'\n", filename);
return false;
}
if (ftell(file) == -1L) {
if (ferror(file)) {
fprintf(stderr, "error: error reading file '%s'\n", filename);
return false;
}
} else {
if (sizeof(T) != 1 && (ftell(file) % sizeof(T))) {
fprintf(
stderr,
"error: file size should be a multiple of %zd; file '%s' corrupt\n",
sizeof(T), filename);
return false;
}
}
return true;
}
} // namespace
bool ReadBinaryFile(const char* filename, std::vector<uint32_t>* data) {
assert(data->empty());
const bool use_file = filename && strcmp("-", filename);
FILE* fp = nullptr;
if (use_file) {
fp = fopen(filename, "rb");
} else {
SET_STDIN_TO_BINARY_MODE();
fp = stdin;
}
ReadFile(fp, data);
bool succeeded = WasFileCorrectlyRead<uint32_t>(fp, filename);
if (use_file && fp) fclose(fp);
return succeeded;
}
bool ReadTextFile(const char* filename, std::vector<char>* data) {
assert(data->empty());
const bool use_file = filename && strcmp("-", filename);
FILE* fp = nullptr;
if (use_file) {
fp = fopen(filename, "r");
} else {
SET_STDIN_TO_TEXT_MODE();
fp = stdin;
}
ReadFile(fp, data);
bool succeeded = WasFileCorrectlyRead<char>(fp, filename);
if (use_file && fp) fclose(fp);
return succeeded;
}
namespace {
// A class to create and manage a file for outputting data.
class OutputFile {
public:
// Opens |filename| in the given mode. If |filename| is nullptr, the empty
// string or "-", stdout will be set to the given mode.
OutputFile(const char* filename, const char* mode) : old_mode_(0) {
const bool use_stdout =
!filename || (filename[0] == '-' && filename[1] == '\0');
if (use_stdout) {
if (strchr(mode, 'b')) {
old_mode_ = SET_STDOUT_TO_BINARY_MODE();
} else {
old_mode_ = SET_STDOUT_TO_TEXT_MODE();
}
fp_ = stdout;
} else {
fp_ = fopen(filename, mode);
}
}
~OutputFile() {
if (fp_ == stdout) {
fflush(stdout);
SET_STDOUT_MODE(old_mode_);
} else if (fp_ != nullptr) {
fclose(fp_);
}
}
// Returns a file handle to the file.
FILE* GetFileHandle() const { return fp_; }
private:
FILE* fp_;
int old_mode_;
};
} // namespace
template <typename T>
bool WriteFile(const char* filename, const char* mode, const T* data,
size_t count) {
OutputFile file(filename, mode);
FILE* fp = file.GetFileHandle();
if (fp == nullptr) {
fprintf(stderr, "error: could not open file '%s'\n", filename);
return false;
}
size_t written = fwrite(data, sizeof(T), count, fp);
if (count != written) {
fprintf(stderr, "error: could not write to file '%s'\n", filename);
return false;
}
return true;
}
template bool WriteFile<uint32_t>(const char* filename, const char* mode,
const uint32_t* data, size_t count);
template bool WriteFile<char>(const char* filename, const char* mode,
const char* data, size_t count);

View File

@ -20,145 +20,19 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#if defined(SPIRV_WINDOWS) // Sets the contents of the file named |filename| in |data|, assuming each
#include <fcntl.h> // element in the file is of type |uint32_t|. The file is opened as a binary
#include <io.h> // file. If |filename| is nullptr or "-", reads from the standard input, but
#define SET_STDIN_TO_BINARY_MODE() _setmode(_fileno(stdin), O_BINARY);
#define SET_STDIN_TO_TEXT_MODE() _setmode(_fileno(stdin), O_TEXT);
#define SET_STDOUT_TO_BINARY_MODE() _setmode(_fileno(stdout), O_BINARY);
#define SET_STDOUT_TO_TEXT_MODE() _setmode(_fileno(stdout), O_TEXT);
#define SET_STDOUT_MODE(mode) _setmode(_fileno(stdout), mode);
#else
#define SET_STDIN_TO_BINARY_MODE()
#define SET_STDIN_TO_TEXT_MODE()
#define SET_STDOUT_TO_BINARY_MODE() 0
#define SET_STDOUT_TO_TEXT_MODE() 0
#define SET_STDOUT_MODE(mode)
#endif
// Appends the contents of the |file| to |data|, assuming each element in the
// file is of type |T|.
template <typename T>
void ReadFile(FILE* file, std::vector<T>* data) {
if (file == nullptr) return;
const int buf_size = 1024;
T buf[buf_size];
while (size_t len = fread(buf, sizeof(T), buf_size, file)) {
data->insert(data->end(), buf, buf + len);
}
}
// Returns true if |file| has encountered an error opening the file or reading
// the file as a series of element of type |T|. If there was an error, writes an
// error message to standard error.
template <class T>
bool WasFileCorrectlyRead(FILE* file, const char* filename) {
if (file == nullptr) {
fprintf(stderr, "error: file does not exist '%s'\n", filename);
return false;
}
if (ftell(file) == -1L) {
if (ferror(file)) {
fprintf(stderr, "error: error reading file '%s'\n", filename);
return false;
}
} else {
if (sizeof(T) != 1 && (ftell(file) % sizeof(T))) {
fprintf(
stderr,
"error: file size should be a multiple of %zd; file '%s' corrupt\n",
sizeof(T), filename);
return false;
}
}
return true;
}
// Appends the contents of the file named |filename| to |data|, assuming
// each element in the file is of type |T|. The file is opened as a binary file
// If |filename| is nullptr or "-", reads from the standard input, but
// reopened as a binary file. If any error occurs, writes error messages to // reopened as a binary file. If any error occurs, writes error messages to
// standard error and returns false. // standard error and returns false.
template <typename T> bool ReadBinaryFile(const char* filename, std::vector<uint32_t>* data);
bool ReadBinaryFile(const char* filename, std::vector<T>* data) {
const bool use_file = filename && strcmp("-", filename);
FILE* fp = nullptr;
if (use_file) {
fp = fopen(filename, "rb");
} else {
SET_STDIN_TO_BINARY_MODE();
fp = stdin;
}
ReadFile(fp, data); // Sets the contents of the file named |filename| in |data|, assuming each
bool succeeded = WasFileCorrectlyRead<T>(fp, filename); // element in the file is of type |char|. The file is opened as a text file. If
if (use_file && fp) fclose(fp); // |filename| is nullptr or "-", reads from the standard input, but reopened as
return succeeded; // a text file. If any error occurs, writes error messages to standard error and
} // returns false.
bool ReadTextFile(const char* filename, std::vector<char>* data);
// Appends the contents of the file named |filename| to |data|, assuming
// each element in the file is of type |T|. The file is opened as a text file
// If |filename| is nullptr or "-", reads from the standard input, but
// reopened as a text file. If any error occurs, writes error messages to
// standard error and returns false.
template <typename T>
bool ReadTextFile(const char* filename, std::vector<T>* data) {
const bool use_file = filename && strcmp("-", filename);
FILE* fp = nullptr;
if (use_file) {
fp = fopen(filename, "r");
} else {
SET_STDIN_TO_TEXT_MODE();
fp = stdin;
}
ReadFile(fp, data);
bool succeeded = WasFileCorrectlyRead<T>(fp, filename);
if (use_file && fp) fclose(fp);
return succeeded;
}
namespace {
// A class to create and manage a file for outputting data.
class OutputFile {
public:
// Opens |filename| in the given mode. If |filename| is nullptr, the empty
// string or "-", stdout will be set to the given mode.
OutputFile(const char* filename, const char* mode) : old_mode_(0) {
const bool use_stdout =
!filename || (filename[0] == '-' && filename[1] == '\0');
if (use_stdout) {
if (strchr(mode, 'b')) {
old_mode_ = SET_STDOUT_TO_BINARY_MODE();
} else {
old_mode_ = SET_STDOUT_TO_TEXT_MODE();
}
fp_ = stdout;
} else {
fp_ = fopen(filename, mode);
}
}
~OutputFile() {
if (fp_ == stdout) {
fflush(stdout);
SET_STDOUT_MODE(old_mode_);
} else if (fp_ != nullptr) {
fclose(fp_);
}
}
// Returns a file handle to the file.
FILE* GetFileHandle() const { return fp_; }
private:
FILE* fp_;
int old_mode_;
};
} // namespace
// Writes the given |data| into the file named as |filename| using the given // Writes the given |data| into the file named as |filename| using the given
// |mode|, assuming |data| is an array of |count| elements of type |T|. If // |mode|, assuming |data| is an array of |count| elements of type |T|. If
@ -166,21 +40,6 @@ class OutputFile {
// returns false and outputs error message to standard error. // returns false and outputs error message to standard error.
template <typename T> template <typename T>
bool WriteFile(const char* filename, const char* mode, const T* data, bool WriteFile(const char* filename, const char* mode, const T* data,
size_t count) { size_t count);
OutputFile file(filename, mode);
FILE* fp = file.GetFileHandle();
if (fp == nullptr) {
fprintf(stderr, "error: could not open file '%s'\n", filename);
return false;
}
size_t written = fwrite(data, sizeof(T), count, fp);
if (count != written) {
fprintf(stderr, "error: could not write to file '%s'\n", filename);
return false;
}
return true;
}
#endif // TOOLS_IO_H_ #endif // TOOLS_IO_H_

View File

@ -143,7 +143,7 @@ int main(int, const char* argv[]) {
std::vector<std::vector<uint32_t>> contents(inFiles.size()); std::vector<std::vector<uint32_t>> contents(inFiles.size());
for (size_t i = 0u; i < inFiles.size(); ++i) { for (size_t i = 0u; i < inFiles.size(); ++i) {
if (!ReadBinaryFile<uint32_t>(inFiles[i].c_str(), &contents[i])) return 1; if (!ReadBinaryFile(inFiles[i].c_str(), &contents[i])) return 1;
} }
const spvtools::MessageConsumer consumer = [](spv_message_level_t level, const spvtools::MessageConsumer consumer = [](spv_message_level_t level,

View File

@ -876,7 +876,7 @@ int main(int argc, const char** argv) {
} }
std::vector<uint32_t> binary; std::vector<uint32_t> binary;
if (!ReadBinaryFile<uint32_t>(in_file, &binary)) { if (!ReadBinaryFile(in_file, &binary)) {
return 1; return 1;
} }

View File

@ -307,7 +307,7 @@ int main(int argc, const char** argv) {
reducer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); reducer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
std::vector<uint32_t> binary_in; std::vector<uint32_t> binary_in;
if (!ReadBinaryFile<uint32_t>(in_binary_file.c_str(), &binary_in)) { if (!ReadBinaryFile(in_binary_file.c_str(), &binary_in)) {
return 1; return 1;
} }

View File

@ -193,7 +193,7 @@ int main(int argc, char** argv) {
} }
std::vector<uint32_t> contents; std::vector<uint32_t> contents;
if (!ReadBinaryFile<uint32_t>(inFile, &contents)) return 1; if (!ReadBinaryFile(inFile, &contents)) return 1;
spvtools::SpirvTools tools(target_env); spvtools::SpirvTools tools(target_env);
tools.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); tools.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);