Break apart `WriteFile` helper.

The write file helper has a bunch of checks for if we're emitting to
`stdout` or a file. The majority of the code is different between the
two paths. This CL splits it into two `Impl` methods which are called by
`WriteFile` based on if the output is to stdout or not.

Change-Id: I5aa21acd8c6e4ea6fcd0cd93c36e05dbd2122ec5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/216495
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/cmd/common/helper.cc b/src/tint/cmd/common/helper.cc
index 98be6ef..9b51808 100644
--- a/src/tint/cmd/common/helper.cc
+++ b/src/tint/cmd/common/helper.cc
@@ -577,4 +577,8 @@
     return "unknown";
 }
 
+bool IsStdout(const std::string& name) {
+    return name.empty() || name == "-";
+}
+
 }  // namespace tint::cmd
diff --git a/src/tint/cmd/common/helper.h b/src/tint/cmd/common/helper.h
index 24327a9..6bb542c 100644
--- a/src/tint/cmd/common/helper.h
+++ b/src/tint/cmd/common/helper.h
@@ -132,6 +132,59 @@
 /// @return the text name
 std::string OverrideTypeToString(tint::inspector::Override::Type type);
 
+/// Returns true if the given `name` is either empty or `-` which signifies `stdout` is selected.
+bool IsStdout(const std::string& name);
+
+/// Writes the given `buffer` to standard output. If any error occurs, returns false and outputs
+/// error message to standard error. The ContainerT type must have data() and size() methods, like
+/// `std::string` and `std::vector` do.
+/// @returns true on success
+/// @private
+template <typename ContainerT>
+bool WriteStdoutImpl(const ContainerT& buffer) {
+    size_t written =
+        fwrite(buffer.data(), sizeof(typename ContainerT::value_type), buffer.size(), stdout);
+    if (buffer.size() != written) {
+        std::cerr << "Could not write all output to standard output\n";
+        return false;
+    }
+    fflush(stdout);
+    return true;
+}
+
+/// Writes the given `buffer` into the file named as `output_file` using the given `mode`. If any
+/// error occurs, returns false and outputs error message to standard error. The ContainerT type
+/// must have data() and size() methods, like `std::string` and `std::vector` do.
+/// @returns true on success
+/// @private
+template <typename ContainerT>
+bool WriteFileImpl(const std::string& output_file,
+                   const std::string mode,
+                   const ContainerT& buffer) {
+    FILE* file = nullptr;
+
+#if defined(_MSC_VER)
+    fopen_s(&file, output_file.c_str(), mode.c_str());
+#else
+    file = fopen(output_file.c_str(), mode.c_str());
+#endif
+    if (!file) {
+        std::cerr << "Could not open file " << output_file << " for writing\n";
+        return false;
+    }
+
+    size_t written =
+        fwrite(buffer.data(), sizeof(typename ContainerT::value_type), buffer.size(), file);
+    if (buffer.size() != written) {
+        std::cerr << "Could not write to file " << output_file << "\n";
+        fclose(file);
+        return false;
+    }
+    fclose(file);
+
+    return true;
+}
+
 /// Writes the given `buffer` into the file named as `output_file` using the
 /// given `mode`.  If `output_file` is empty or "-", writes to standard
 /// output. If any error occurs, returns false and outputs error message to
@@ -140,39 +193,10 @@
 /// @returns true on success
 template <typename ContainerT>
 bool WriteFile(const std::string& output_file, const std::string mode, const ContainerT& buffer) {
-    const bool use_stdout = output_file.empty() || output_file == "-";
-    FILE* file = stdout;
-
-    if (!use_stdout) {
-#if defined(_MSC_VER)
-        fopen_s(&file, output_file.c_str(), mode.c_str());
-#else
-        file = fopen(output_file.c_str(), mode.c_str());
-#endif
-        if (!file) {
-            std::cerr << "Could not open file " << output_file << " for writing\n";
-            return false;
-        }
+    if (IsStdout(output_file)) {
+        return WriteStdoutImpl(buffer);
     }
-
-    size_t written =
-        fwrite(buffer.data(), sizeof(typename ContainerT::value_type), buffer.size(), file);
-    if (buffer.size() != written) {
-        if (use_stdout) {
-            std::cerr << "Could not write all output to standard output\n";
-        } else {
-            std::cerr << "Could not write to file " << output_file << "\n";
-            fclose(file);
-        }
-        return false;
-    }
-    if (use_stdout) {
-        fflush(file);
-    } else {
-        fclose(file);
-    }
-
-    return true;
+    return WriteFileImpl(output_file, mode, buffer);
 }
 
 /// Copies the content from the file named `input_file` to `buffer`,