[tint] Wrap accessing argc & argv to remove suppressions This adds in an utility for converting argc & argv passed into main() into a tint::Vector of the arguments. This is done because it is a known issue that accessing the c-style argv will always cause `-Wunsafe-buffer-usage` to fire, and this wrapper isolates this known needed suppression into a single location instead of being scattered across the code base. This CL cleans up a bunch of main.cc files using this new utility, though there is a couple exceptions. In remote_compile/main.cc the suppression is just narrowed, since there is non-main related issues in that file. There are some other main.cc files, like for the benchmark tool, that use a different broader suppression that are not touched. Bug: 394825124 Change-Id: I92ea0fbc0012ef0900214a1eaefc9fb89a63553d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/224915 Reviewed-by: dan sinclair <dsinclair@chromium.org> Auto-Submit: Ryan Harrison <rharrison@chromium.org> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/cmd/fuzz/ir/as/main.cc b/src/tint/cmd/fuzz/ir/as/main.cc index a9b6f2b..6d62e38 100644 --- a/src/tint/cmd/fuzz/ir/as/main.cc +++ b/src/tint/cmd/fuzz/ir/as/main.cc
@@ -39,6 +39,7 @@ #include "src/tint/lang/wgsl/ast/module.h" #include "src/tint/lang/wgsl/helpers/apply_substitute_overrides.h" #include "src/tint/lang/wgsl/reader/reader.h" +#include "src/tint/utils/command/args.h" #include "src/tint/utils/command/cli.h" #include "src/tint/utils/containers/transform.h" #include "src/tint/utils/macros/defer.h" @@ -51,8 +52,6 @@ #include "src/tint/utils/protos/ir_fuzz/ir_fuzz.pb.h" TINT_END_DISABLE_PROTOBUF_WARNINGS(); -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { struct Options { @@ -280,14 +279,7 @@ } // namespace int main(int argc, const char** argv) { - tint::Vector<std::string_view, 8> arguments; - for (int i = 1; i < argc; i++) { - std::string_view arg(argv[i]); - if (!arg.empty()) { - arguments.Push(argv[i]); - } - } - + tint::Vector<std::string_view, 8> arguments = tint::args::Vectorize(argc, argv); Options options; tint::Initialize(); @@ -341,5 +333,3 @@ return EXIT_SUCCESS; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/cmd/fuzz/ir/dis/main.cc b/src/tint/cmd/fuzz/ir/dis/main.cc index 9b2e5e5..4923a3e 100644 --- a/src/tint/cmd/fuzz/ir/dis/main.cc +++ b/src/tint/cmd/fuzz/ir/dis/main.cc
@@ -36,6 +36,7 @@ #include "src/tint/lang/core/ir/disassembler.h" #include "src/tint/lang/spirv/writer/writer.h" #include "src/tint/lang/wgsl/writer/writer.h" +#include "src/tint/utils/command/args.h" #include "src/tint/utils/command/cli.h" #include "src/tint/utils/containers/transform.h" #include "src/tint/utils/macros/defer.h" @@ -50,8 +51,6 @@ #include "src/tint/utils/protos/ir_fuzz/ir_fuzz.pb.h" TINT_END_DISABLE_PROTOBUF_WARNINGS(); -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { /// @param data spriv shader to be converted @@ -386,14 +385,7 @@ } // namespace int main(int argc, const char** argv) { - tint::Vector<std::string_view, 8> arguments; - for (int i = 1; i < argc; i++) { - std::string_view arg(argv[i]); - if (!arg.empty()) { - arguments.Push(argv[i]); - } - } - + tint::Vector<std::string_view, 8> arguments = tint::args::Vectorize(argc, argv); Options options; tint::Initialize(); @@ -413,5 +405,3 @@ return EXIT_SUCCESS; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/cmd/info/BUILD.bazel b/src/tint/cmd/info/BUILD.bazel index 36573a1..532bc65 100644 --- a/src/tint/cmd/info/BUILD.bazel +++ b/src/tint/cmd/info/BUILD.bazel
@@ -55,6 +55,7 @@ "//src/tint/lang/wgsl/program", "//src/tint/lang/wgsl/sem", "//src/tint/utils", + "//src/tint/utils/command", "//src/tint/utils/containers", "//src/tint/utils/diagnostic", "//src/tint/utils/ice",
diff --git a/src/tint/cmd/info/BUILD.cmake b/src/tint/cmd/info/BUILD.cmake index c7b8af0..4d83eb8 100644 --- a/src/tint/cmd/info/BUILD.cmake +++ b/src/tint/cmd/info/BUILD.cmake
@@ -56,6 +56,7 @@ tint_lang_wgsl_program tint_lang_wgsl_sem tint_utils + tint_utils_command tint_utils_containers tint_utils_diagnostic tint_utils_ice
diff --git a/src/tint/cmd/info/BUILD.gn b/src/tint/cmd/info/BUILD.gn index 8d245c3..53efac9 100644 --- a/src/tint/cmd/info/BUILD.gn +++ b/src/tint/cmd/info/BUILD.gn
@@ -57,6 +57,7 @@ "${tint_src_dir}/lang/wgsl/program", "${tint_src_dir}/lang/wgsl/sem", "${tint_src_dir}/utils", + "${tint_src_dir}/utils/command", "${tint_src_dir}/utils/containers", "${tint_src_dir}/utils/diagnostic", "${tint_src_dir}/utils/ice",
diff --git a/src/tint/cmd/info/main.cc b/src/tint/cmd/info/main.cc index 7943cb6..73dd517 100644 --- a/src/tint/cmd/info/main.cc +++ b/src/tint/cmd/info/main.cc
@@ -33,10 +33,9 @@ #include "src/tint/cmd/common/helper.h" #include "src/tint/lang/core/type/struct.h" #include "src/tint/lang/wgsl/inspector/entry_point.h" +#include "src/tint/utils/command/args.h" #include "src/tint/utils/text/string.h" -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { struct Options { @@ -58,9 +57,8 @@ )"; -bool ParseArgs(const std::vector<std::string>& args, Options* opts) { - for (size_t i = 1; i < args.size(); ++i) { - const std::string& arg = args[i]; +bool ParseArgs(tint::VectorRef<std::string_view> args, Options* opts) { + for (auto arg : args) { if (arg == "-h" || arg == "--help") { opts->show_help = true; } else if (arg == "--json") { @@ -295,7 +293,7 @@ } // namespace int main(int argc, const char** argv) { - std::vector<std::string> args(argv, argv + argc); + tint::Vector<std::string_view, 8> args = tint::args::Vectorize(argc, argv); Options options; tint::SetInternalCompilerErrorReporter(&tint::cmd::TintInternalCompilerErrorReporter); @@ -326,5 +324,3 @@ return 0; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/cmd/loopy/BUILD.bazel b/src/tint/cmd/loopy/BUILD.bazel index 362258f..b4c774c 100644 --- a/src/tint/cmd/loopy/BUILD.bazel +++ b/src/tint/cmd/loopy/BUILD.bazel
@@ -62,6 +62,7 @@ "//src/tint/lang/wgsl/sem", "//src/tint/lang/wgsl/writer/ir_to_program", "//src/tint/utils", + "//src/tint/utils/command", "//src/tint/utils/containers", "//src/tint/utils/diagnostic", "//src/tint/utils/ice",
diff --git a/src/tint/cmd/loopy/BUILD.cmake b/src/tint/cmd/loopy/BUILD.cmake index c1dddb7..d45bb63 100644 --- a/src/tint/cmd/loopy/BUILD.cmake +++ b/src/tint/cmd/loopy/BUILD.cmake
@@ -63,6 +63,7 @@ tint_lang_wgsl_sem tint_lang_wgsl_writer_ir_to_program tint_utils + tint_utils_command tint_utils_containers tint_utils_diagnostic tint_utils_ice
diff --git a/src/tint/cmd/loopy/BUILD.gn b/src/tint/cmd/loopy/BUILD.gn index 28abd46..6eb72be 100644 --- a/src/tint/cmd/loopy/BUILD.gn +++ b/src/tint/cmd/loopy/BUILD.gn
@@ -64,6 +64,7 @@ "${tint_src_dir}/lang/wgsl/sem", "${tint_src_dir}/lang/wgsl/writer/ir_to_program", "${tint_src_dir}/utils", + "${tint_src_dir}/utils/command", "${tint_src_dir}/utils/containers", "${tint_src_dir}/utils/diagnostic", "${tint_src_dir}/utils/ice",
diff --git a/src/tint/cmd/loopy/main.cc b/src/tint/cmd/loopy/main.cc index 57a90e5..19dbef7 100644 --- a/src/tint/cmd/loopy/main.cc +++ b/src/tint/cmd/loopy/main.cc
@@ -29,6 +29,7 @@ #include "src/tint/api/tint.h" #include "src/tint/cmd/common/helper.h" +#include "src/tint/utils/command/args.h" #if TINT_BUILD_GLSL_WRITER #include "src/tint/lang/glsl/writer/helpers/generate_bindings.h" @@ -64,8 +65,6 @@ #include "src/tint/lang/wgsl/writer/writer.h" #endif // TINT_BUILD_WGSL_WRITER -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { enum class Format { @@ -102,7 +101,7 @@ --loop-count <num> -- Number of loops to run, default 100. )"; -Format parse_format(const std::string& fmt) { +Format parse_format(const std::string_view fmt) { (void)fmt; #if TINT_BUILD_SPV_WRITER @@ -142,12 +141,12 @@ return Format::kUnknown; } -bool ParseArgs(const std::vector<std::string>& args, Options* opts) { - for (size_t i = 1; i < args.size(); ++i) { - const std::string& arg = args[i]; +bool ParseArgs(tint::VectorRef<std::string_view> args, Options* opts) { + for (size_t i = 1; i < args.Length(); ++i) { + auto arg = args[i]; if (arg == "--format") { ++i; - if (i >= args.size()) { + if (i >= args.Length()) { std::cerr << "Missing value for --format argument.\n"; return false; } @@ -161,7 +160,7 @@ opts->show_help = true; } else if (arg == "--loop") { ++i; - if (i >= args.size()) { + if (i >= args.Length()) { std::cerr << "Missing value for --loop argument.\n"; return false; } @@ -177,11 +176,11 @@ } } else if (arg == "--loop-count") { ++i; - if (i >= args.size()) { + if (i >= args.Length()) { std::cerr << "Missing value for --loop-count argument.\n"; return false; } - int32_t val = atoi(args[i].c_str()); + int32_t val = atoi(std::string(args[i]).c_str()); if (val <= 0) { std::cerr << "Loop count must be greater then 0\n"; return false; @@ -353,7 +352,7 @@ } // namespace int main(int argc, const char** argv) { - std::vector<std::string> args(argv, argv + argc); + tint::Vector<std::string_view, 8> args = tint::args::Vectorize(argc, argv); Options options; tint::Initialize(); @@ -481,5 +480,3 @@ return 0; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/cmd/remote_compile/BUILD.bazel b/src/tint/cmd/remote_compile/BUILD.bazel index 7abc45c..ba232a4 100644 --- a/src/tint/cmd/remote_compile/BUILD.bazel +++ b/src/tint/cmd/remote_compile/BUILD.bazel
@@ -43,7 +43,13 @@ ], deps = [ "//src/tint/utils", + "//src/tint/utils/command", + "//src/tint/utils/containers", + "//src/tint/utils/ice", "//src/tint/utils/macros", + "//src/tint/utils/math", + "//src/tint/utils/memory", + "//src/tint/utils/rtti", "//src/utils", ] + select({
diff --git a/src/tint/cmd/remote_compile/BUILD.cmake b/src/tint/cmd/remote_compile/BUILD.cmake index 0d00547..23ea113 100644 --- a/src/tint/cmd/remote_compile/BUILD.cmake +++ b/src/tint/cmd/remote_compile/BUILD.cmake
@@ -44,7 +44,13 @@ tint_target_add_dependencies(tint_cmd_remote_compile_cmd cmd tint_utils + tint_utils_command + tint_utils_containers + tint_utils_ice tint_utils_macros + tint_utils_math + tint_utils_memory + tint_utils_rtti ) tint_target_add_external_dependencies(tint_cmd_remote_compile_cmd cmd
diff --git a/src/tint/cmd/remote_compile/BUILD.gn b/src/tint/cmd/remote_compile/BUILD.gn index 2f22f2d..dc1f904 100644 --- a/src/tint/cmd/remote_compile/BUILD.gn +++ b/src/tint/cmd/remote_compile/BUILD.gn
@@ -46,7 +46,13 @@ "${dawn_root}/src/utils:utils", "${tint_src_dir}:thread", "${tint_src_dir}/utils", + "${tint_src_dir}/utils/command", + "${tint_src_dir}/utils/containers", + "${tint_src_dir}/utils/ice", "${tint_src_dir}/utils/macros", + "${tint_src_dir}/utils/math", + "${tint_src_dir}/utils/memory", + "${tint_src_dir}/utils/rtti", ] if (tint_build_msl_writer) {
diff --git a/src/tint/cmd/remote_compile/main.cc b/src/tint/cmd/remote_compile/main.cc index 38aa37a..962cc86 100644 --- a/src/tint/cmd/remote_compile/main.cc +++ b/src/tint/cmd/remote_compile/main.cc
@@ -40,11 +40,10 @@ #include "src/tint/lang/msl/validate/validate.h" #endif +#include "src/tint/utils/command/args.h" #include "src/tint/utils/macros/compiler.h" #include "src/tint/utils/socket.h" -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { /// The return structure of a compile function @@ -158,6 +157,7 @@ return error.empty(); } + TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); bool Read(void* data, size_t size) { auto buf = reinterpret_cast<uint8_t*>(data); while (size > 0 && error.empty()) { @@ -174,6 +174,7 @@ } return error.empty(); } + TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); }; //////////////////////////////////////////////////////////////////////////////// @@ -309,7 +310,7 @@ int version_minor, bool verbose); -int main(int argc, char* argv[]) { +int main(int argc, const char** argv) { bool run_server = false; bool verbose = false; int version_major = 0; @@ -318,17 +319,18 @@ std::regex metal_version_re{"^-?-std=macos-metal([0-9]+)\\.([0-9]+)"}; - std::vector<std::string> args; - for (int i = 1; i < argc; i++) { - std::string arg = argv[i]; + auto args = tint::args::Vectorize(argc, argv); + std::vector<std::string> parsed_args; + for (size_t i = 0; i < args.Length(); i++) { + std::string arg = std::string(args[i]); if (arg == "-s" || arg == "--server") { run_server = true; continue; } if (arg == "-p" || arg == "--port") { - if (i < argc - 1) { + if (i < args.Length() - 1) { i++; - port = argv[i]; + port = args[i]; } else { printf("expected port number"); exit(1); @@ -341,13 +343,13 @@ } // xcrun flags are ignored so this executable can be used as a replacement for xcrun. - if ((arg == "-x" || arg == "-sdk") && (i < argc - 1)) { + if ((arg == "-x" || arg == "-sdk") && (i < args.Length() - 1)) { i++; continue; } if (arg == "metal") { - for (; i < argc; i++) { - arg = argv[i]; + for (; i < args.Length(); i++) { + arg = args[i]; // metal_version_re std::smatch metal_version_match; if (std::regex_match(arg, metal_version_match, metal_version_re)) { @@ -362,7 +364,7 @@ continue; } - args.emplace_back(arg); + parsed_args.emplace_back(arg); } bool success = false; @@ -372,21 +374,21 @@ } else { std::string address; std::string file; - switch (args.size()) { + switch (parsed_args.size()) { case 1: TINT_BEGIN_DISABLE_WARNING(DEPRECATED); if (auto* addr = getenv("TINT_REMOTE_COMPILE_ADDRESS")) { address = addr; } TINT_END_DISABLE_WARNING(DEPRECATED); - file = args[0]; + file = parsed_args[0]; break; case 2: - address = args[0]; - file = args[1]; + address = parsed_args[0]; + file = parsed_args[1]; break; default: - std::cerr << "Expected 1 or 2 arguments, got " << args.size() << "\n\n"; + std::cerr << "Expected 1 or 2 arguments, got " << parsed_args.size() << "\n\n"; ShowUsage(); } if (address.empty() || file.empty()) { @@ -532,5 +534,3 @@ } return true; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc index 7946de5..59057b6 100644 --- a/src/tint/cmd/tint/main.cc +++ b/src/tint/cmd/tint/main.cc
@@ -33,6 +33,7 @@ #include <unordered_map> #include <vector> #include "src/tint/lang/wgsl/sem/variable.h" +#include "src/tint/utils/command/args.h" #include "src/tint/utils/text/color_mode.h" #if TINT_BUILD_SPV_READER || TINT_BUILD_SPV_WRITER @@ -98,8 +99,6 @@ #include "src/tint/lang/glsl/validate/validate.h" #endif // TINT_BUILD_GLSL_VALIDATOR -TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); - namespace { /// Prints the given hash value in a format string that the end-to-end test runner can parse. @@ -220,6 +219,9 @@ return Format::kUnknown; } +// The actual warning occurs on `std::from_chars(hash.data(), hash.data() + hash.size(), value, +// base);`, but disabling/enabling warnings cannot be done within function scope +TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); bool ParseArgs(tint::VectorRef<std::string_view> arguments, Options* opts) { using namespace tint::cli; // NOLINT(build/namespaces) @@ -366,6 +368,7 @@ hash = hash.substr(2); base = 16; } + std::from_chars(hash.data(), hash.data() + hash.size(), value, base); opts->skip_hash.emplace(value); } @@ -589,6 +592,7 @@ return true; } +TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); [[maybe_unused]] void AddRenamer(Options& options, tint::ast::transform::Manager& transform_manager, @@ -1290,14 +1294,7 @@ } // namespace int main(int argc, const char** argv) { - tint::Vector<std::string_view, 8> arguments; - for (int i = 1; i < argc; i++) { - std::string_view arg(argv[i]); - if (!arg.empty()) { - arguments.Push(argv[i]); - } - } - + tint::Vector<std::string_view, 8> arguments = tint::args::Vectorize(argc, argv); Options options; tint::Initialize(); @@ -1434,5 +1431,3 @@ } return success ? 0 : 1; } - -TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/utils/command/BUILD.bazel b/src/tint/utils/command/BUILD.bazel index 95d839e..4d8aecb 100644 --- a/src/tint/utils/command/BUILD.bazel +++ b/src/tint/utils/command/BUILD.bazel
@@ -39,6 +39,7 @@ cc_library( name = "command", srcs = [ + "args.cc", "cli.cc", ] + select({ ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [ @@ -57,6 +58,7 @@ "//conditions:default": [], }), hdrs = [ + "args.h", "cli.h", "command.h", ],
diff --git a/src/tint/utils/command/BUILD.cmake b/src/tint/utils/command/BUILD.cmake index 6724b16..8d730ef 100644 --- a/src/tint/utils/command/BUILD.cmake +++ b/src/tint/utils/command/BUILD.cmake
@@ -39,6 +39,8 @@ # Kind: lib ################################################################################ tint_add_target(tint_utils_command lib + utils/command/args.cc + utils/command/args.h utils/command/cli.cc utils/command/cli.h utils/command/command.h
diff --git a/src/tint/utils/command/BUILD.gn b/src/tint/utils/command/BUILD.gn index 03e801a..86a0acb 100644 --- a/src/tint/utils/command/BUILD.gn +++ b/src/tint/utils/command/BUILD.gn
@@ -45,6 +45,8 @@ libtint_source_set("command") { sources = [ + "args.cc", + "args.h", "cli.cc", "cli.h", "command.h",
diff --git a/src/tint/utils/command/args.cc b/src/tint/utils/command/args.cc new file mode 100644 index 0000000..fb91a47 --- /dev/null +++ b/src/tint/utils/command/args.cc
@@ -0,0 +1,46 @@ +// Copyright 2025 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "src/tint/utils/command/args.h" + +namespace tint::args { + +// Working with argv is known to always cause this warning to fire +TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); +tint::Vector<std::string_view, 8> Vectorize(int argc, const char** argv) { + tint::Vector<std::string_view, 8> arguments; + for (int i = 1; i < argc; i++) { + std::string_view arg(argv[i]); + if (!arg.empty()) { + arguments.Push(argv[i]); + } + } + return arguments; +} +TINT_END_DISABLE_WARNING(UNSAFE_BUFFER_USAGE); + +} // namespace tint::args
diff --git a/src/tint/utils/command/args.h b/src/tint/utils/command/args.h new file mode 100644 index 0000000..dceb4e5 --- /dev/null +++ b/src/tint/utils/command/args.h
@@ -0,0 +1,46 @@ +// Copyright 2025 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef SRC_TINT_UTILS_COMMAND_ARGS_H_ +#define SRC_TINT_UTILS_COMMAND_ARGS_H_ + +#include <string> + +#include "src/tint/utils/containers/vector.h" + +namespace tint::args { + +/// Converts the c-style program arguments into a safer C++ style vector. +/// Note: This is done to isolate code that is known to cause compiler warnings to a single location +/// @param argc number of arguments supplied to program, |argc| in main() +/// @param argv array of argument strings supplied to program, |argv| in main() +/// @returns a vector of string_views containing the argument strings +tint::Vector<std::string_view, 8> Vectorize(int argc, const char** argv); + +} // namespace tint::args + +#endif // SRC_TINT_UTILS_COMMAND_ARGS_H_