Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSteven Perron <stevenperron@google.com>2022-06-29 22:40:29 +0300
committerGitHub <noreply@github.com>2022-06-29 22:40:29 +0300
commit91572e769ad62bc22d482af225eb3f04188825a0 (patch)
tree1ef055136981272b7f8042f2418cac42527e6b5e /tools
parent0b824324bc8dd21003e6c028df940f0399d88a03 (diff)
Write binary files to stdout in binary on windows. (#4834)
We currently do not set stdout to binary mode when writing a binary file on Windows. This cause some extra characters to be written that mess up the output. We try to fix that. Fixes #4793
Diffstat (limited to 'tools')
-rw-r--r--tools/io.h65
1 files changed, 54 insertions, 11 deletions
diff --git a/tools/io.h b/tools/io.h
index 83a85c1d1..9dc834edf 100644
--- a/tools/io.h
+++ b/tools/io.h
@@ -26,9 +26,15 @@
#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
@@ -115,6 +121,44 @@ bool ReadTextFile(const char* filename, std::vector<T>* data) {
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) {
+ 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) {
+ 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
// |mode|, assuming |data| is an array of |count| elements of type |T|. If
// |filename| is nullptr or "-", writes to standard output. If any error occurs,
@@ -122,20 +166,19 @@ bool ReadTextFile(const char* filename, std::vector<T>* data) {
template <typename T>
bool WriteFile(const char* filename, const char* mode, const T* data,
size_t count) {
- const bool use_stdout =
- !filename || (filename[0] == '-' && filename[1] == '\0');
- if (FILE* fp = (use_stdout ? stdout : fopen(filename, mode))) {
- size_t written = fwrite(data, sizeof(T), count, fp);
- if (count != written) {
- fprintf(stderr, "error: could not write to file '%s'\n", filename);
- if (!use_stdout) fclose(fp);
- return false;
- }
- if (!use_stdout) fclose(fp);
- } else {
+ 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;
}