mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-21 19:20:07 +00:00
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:
parent
ce92630396
commit
5f1e86cb55
@ -269,6 +269,7 @@ cc_library(
|
||||
cc_library(
|
||||
name = "tools_io",
|
||||
hdrs = ["tools/io.h"],
|
||||
srcs = ["tools/io.cpp"],
|
||||
copts = COMMON_COPTS,
|
||||
)
|
||||
|
||||
|
17
BUILD.gn
17
BUILD.gn
@ -1466,6 +1466,15 @@ source_set("spvtools_tools_util") {
|
||||
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) {
|
||||
executable("spirv-as") {
|
||||
sources = [ "tools/as/as.cpp" ]
|
||||
@ -1473,6 +1482,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
}
|
||||
@ -1483,6 +1493,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
}
|
||||
@ -1493,6 +1504,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
":spvtools_val",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
@ -1508,6 +1520,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
}
|
||||
@ -1519,6 +1532,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools_opt",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
":spvtools_val",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
@ -1532,6 +1546,7 @@ if (spvtools_build_executables) {
|
||||
":spvtools_opt",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
":spvtools_val",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
@ -1552,6 +1567,7 @@ if (!is_ios && !spirv_is_winuwp && build_with_chromium && spvtools_build_executa
|
||||
":spvtools_reduce",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
":spvtools_val",
|
||||
"//third_party/protobuf:protobuf_full",
|
||||
]
|
||||
@ -1571,6 +1587,7 @@ if (!is_ios && !spirv_is_winuwp && spvtools_build_executables) {
|
||||
":spvtools_reduce",
|
||||
":spvtools_software_version",
|
||||
":spvtools_tools_util",
|
||||
":spvtools_tools_io",
|
||||
":spvtools_val",
|
||||
]
|
||||
configs += [ ":spvtools_internal_config" ]
|
||||
|
@ -123,7 +123,8 @@ if (${SPIRV_BUILD_FUZZER})
|
||||
transformation_wrap_early_terminator_in_function_test.cpp
|
||||
transformation_wrap_region_in_selection_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})
|
||||
# These are long-running tests that depend on random seeds. We do not want
|
||||
|
@ -31,6 +31,7 @@ add_spvtools_unittest(TARGET reduce
|
||||
structured_construct_to_block_test.cpp
|
||||
structured_loop_to_selection_test.cpp
|
||||
validation_during_reduction_test.cpp
|
||||
${spirv-tools_SOURCE_DIR}/tools/io.cpp
|
||||
LIBS SPIRV-Tools-reduce
|
||||
)
|
||||
|
||||
|
@ -42,17 +42,18 @@ endfunction()
|
||||
set(COMMON_TOOLS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/util/flags.cpp")
|
||||
|
||||
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-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.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-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-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 io.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 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
|
||||
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()
|
||||
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-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-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 io.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
add_spvtools_tool(TARGET spirv-as
|
||||
SRCS as/as.cpp
|
||||
io.cpp
|
||||
${COMMON_TOOLS_SRCS}
|
||||
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
target_include_directories(spirv-as PRIVATE ${spirv-tools_SOURCE_DIR}
|
||||
@ -61,6 +62,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
|
||||
SRCS cfg/cfg.cpp
|
||||
cfg/bin_to_dot.h
|
||||
cfg/bin_to_dot.cpp
|
||||
io.cpp
|
||||
${COMMON_TOOLS_SRCS}
|
||||
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR}
|
||||
@ -73,6 +75,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
|
||||
SRCS objdump/objdump.cpp
|
||||
objdump/extract_source.cpp
|
||||
util/cli_consumer.cpp
|
||||
io.cpp
|
||||
${COMMON_TOOLS_SRCS}
|
||||
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
target_include_directories(spirv-objdump PRIVATE ${spirv-tools_SOURCE_DIR}
|
||||
@ -85,7 +88,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
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)
|
||||
endif(SPIRV_BUILD_FUZZER)
|
||||
|
||||
|
@ -106,7 +106,7 @@ int main(int, const char** argv) {
|
||||
std::string inFile = flags::positional_arguments[0];
|
||||
|
||||
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_diagnostic diagnostic = nullptr;
|
||||
|
@ -75,7 +75,7 @@ int main(int, const char** argv) {
|
||||
|
||||
// Read the input binary.
|
||||
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_diagnostic diagnostic = nullptr;
|
||||
|
||||
|
@ -82,7 +82,7 @@ bool is_assembly(const char* path) {
|
||||
std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
|
||||
if (is_assembly(path)) {
|
||||
std::vector<char> contents;
|
||||
if (!ReadTextFile<char>(path, &contents)) return {};
|
||||
if (!ReadTextFile(path, &contents)) return {};
|
||||
|
||||
return spvtools::BuildModule(
|
||||
kDefaultEnvironment, spvtools::utils::CLIMessageConsumer,
|
||||
@ -92,7 +92,7 @@ std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
|
||||
}
|
||||
|
||||
std::vector<uint32_t> contents;
|
||||
if (!ReadBinaryFile<uint32_t>(path, &contents)) return {};
|
||||
if (!ReadBinaryFile(path, &contents)) return {};
|
||||
|
||||
return spvtools::BuildModule(kDefaultEnvironment,
|
||||
spvtools::utils::CLIMessageConsumer,
|
||||
|
@ -153,7 +153,7 @@ int main(int, const char** argv) {
|
||||
|
||||
// Read the input binary.
|
||||
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
|
||||
// do the printing. In particular, colour printing on Windows is
|
||||
|
@ -584,8 +584,7 @@ bool Fuzz(const spv_target_env& target_env,
|
||||
[donor_filename, message_consumer,
|
||||
target_env]() -> std::unique_ptr<spvtools::opt::IRContext> {
|
||||
std::vector<uint32_t> donor_binary;
|
||||
if (!ReadBinaryFile<uint32_t>(donor_filename.c_str(),
|
||||
&donor_binary)) {
|
||||
if (!ReadBinaryFile(donor_filename.c_str(), &donor_binary)) {
|
||||
return nullptr;
|
||||
}
|
||||
return spvtools::BuildModule(target_env, message_consumer,
|
||||
@ -712,7 +711,7 @@ int main(int argc, const char** argv) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
175
tools/io.cpp
Normal file
175
tools/io.cpp
Normal 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);
|
163
tools/io.h
163
tools/io.h
@ -20,145 +20,19 @@
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
// 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
|
||||
// Sets the contents of the file named |filename| in |data|, assuming each
|
||||
// element in the file is of type |uint32_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
|
||||
// standard error and returns false.
|
||||
template <typename T>
|
||||
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;
|
||||
}
|
||||
bool ReadBinaryFile(const char* filename, std::vector<uint32_t>* data);
|
||||
|
||||
ReadFile(fp, data);
|
||||
bool succeeded = WasFileCorrectlyRead<T>(fp, filename);
|
||||
if (use_file && fp) fclose(fp);
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// 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
|
||||
// Sets the contents of the file named |filename| in |data|, assuming each
|
||||
// element in the file is of type |char|. 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.
|
||||
bool ReadTextFile(const char* filename, std::vector<char>* data);
|
||||
|
||||
// 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
|
||||
@ -166,21 +40,6 @@ class OutputFile {
|
||||
// returns false and outputs error message to standard error.
|
||||
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;
|
||||
}
|
||||
size_t count);
|
||||
|
||||
#endif // TOOLS_IO_H_
|
||||
|
@ -143,7 +143,7 @@ int main(int, const char* argv[]) {
|
||||
|
||||
std::vector<std::vector<uint32_t>> contents(inFiles.size());
|
||||
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,
|
||||
|
@ -876,7 +876,7 @@ int main(int argc, const char** argv) {
|
||||
}
|
||||
|
||||
std::vector<uint32_t> binary;
|
||||
if (!ReadBinaryFile<uint32_t>(in_file, &binary)) {
|
||||
if (!ReadBinaryFile(in_file, &binary)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ int main(int argc, const char** argv) {
|
||||
reducer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
std::vector<uint32_t> contents;
|
||||
if (!ReadBinaryFile<uint32_t>(inFile, &contents)) return 1;
|
||||
if (!ReadBinaryFile(inFile, &contents)) return 1;
|
||||
|
||||
spvtools::SpirvTools tools(target_env);
|
||||
tools.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
|
||||
|
Loading…
Reference in New Issue
Block a user