| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #include "toolchain/driver/format_subcommand.h"
- #include <string>
- #include "toolchain/base/shared_value_stores.h"
- #include "toolchain/diagnostics/diagnostic_consumer.h"
- #include "toolchain/format/format.h"
- #include "toolchain/lex/lex.h"
- #include "toolchain/source/source_buffer.h"
- namespace Carbon {
- auto FormatOptions::Build(CommandLine::CommandBuilder& b) -> void {
- b.AddStringPositionalArg(
- {
- .name = "FILE",
- .help = R"""(
- The input Carbon source file(s) to format.
- )""",
- },
- [&](auto& arg_b) {
- arg_b.Required(true);
- arg_b.Append(&input_filenames);
- });
- b.AddStringOption(
- {
- .name = "output",
- .value_name = "FILE",
- .help = R"""(
- The output filename for formatted output.
- By default, the input file is formatted. Passing `--output=-` will write the
- output to stdout.
- Not valid when multiple files are passed for formatting.
- )""",
- },
- [&](auto& arg_b) { arg_b.Set(&output_filename); });
- }
- static constexpr CommandLine::CommandInfo SubcommandInfo = {
- .name = "format",
- .help = R"""(
- Format Carbon source code.
- )""",
- };
- FormatSubcommand::FormatSubcommand() : DriverSubcommand(SubcommandInfo) {}
- auto FormatSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
- DriverResult result = {.success = true};
- if (options_.input_filenames.size() > 1 &&
- !options_.output_filename.empty()) {
- driver_env.error_stream << "error: cannot format multiple input files when "
- "--output is set\n";
- result.success = false;
- return result;
- }
- auto mark_per_file_error = [&]() {
- result.success = false;
- result.per_file_success.back().second = false;
- };
- StreamDiagnosticConsumer consumer(driver_env.error_stream,
- /*include_diagnostic_kind=*/false);
- for (auto& f : options_.input_filenames) {
- // Push a result, which we'll update on failure.
- result.per_file_success.push_back({f.str(), true});
- // TODO: Consider refactoring this for sharing with compile.
- // TODO: Decide what to do with `-` when there are multiple arguments.
- auto source = SourceBuffer::MakeFromFileOrStdin(driver_env.fs, f, consumer);
- if (!source) {
- mark_per_file_error();
- continue;
- }
- SharedValueStores value_stores;
- auto tokens = Lex::Lex(value_stores, *source, consumer);
- std::string buffer_str;
- llvm::raw_string_ostream buffer(buffer_str);
- if (Format::Format(tokens, buffer)) {
- // TODO: Figure out a multi-file output setup that supports good
- // multi-file testing.
- // TODO: Use --output values (and default to overwrite).
- driver_env.output_stream << buffer_str;
- } else {
- mark_per_file_error();
- driver_env.output_stream << source->text();
- }
- }
- return result;
- }
- } // namespace Carbon
|