diff options
Diffstat (limited to 'tools/aapt2/Main.cpp')
-rw-r--r-- | tools/aapt2/Main.cpp | 180 |
1 files changed, 97 insertions, 83 deletions
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 808b29cfd844..23903c9e05f3 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -29,6 +29,13 @@ #include "androidfw/StringPiece.h" #include "Diagnostics.h" +#include "cmd/Command.h" +#include "cmd/Compile.h" +#include "cmd/Convert.h" +#include "cmd/Diff.h" +#include "cmd/Dump.h" +#include "cmd/Link.h" +#include "cmd/Optimize.h" #include "util/Files.h" #include "util/Util.h" @@ -43,114 +50,121 @@ static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. static const char* sMinorVersion = "19"; -static void PrintVersion() { - std::cerr << StringPrintf("Android Asset Packaging Tool (aapt) %s:%s", sMajorVersion, - sMinorVersion) - << std::endl; -} - -static void PrintUsage() { - std::cerr << "\nusage: aapt2 [compile|link|dump|diff|optimize|convert|version] ..." << std::endl; -} +/** Prints the version information of AAPT2. */ +class VersionCommand : public Command { + public: + explicit VersionCommand() : Command("version") { + SetDescription("Prints the version of aapt."); + } -extern int Compile(const std::vector<StringPiece>& args, IDiagnostics* diagnostics); -extern int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics); -extern int Dump(const std::vector<StringPiece>& args); -extern int Diff(const std::vector<StringPiece>& args); -extern int Optimize(const std::vector<StringPiece>& args); -extern int Convert(const std::vector<StringPiece>& args); - -static int ExecuteCommand(const StringPiece& command, const std::vector<StringPiece>& args, - IDiagnostics* diagnostics) { - if (command == "compile" || command == "c") { - return Compile(args, diagnostics); - } else if (command == "link" || command == "l") { - return Link(args, diagnostics); - } else if (command == "dump" || command == "d") { - return Dump(args); - } else if (command == "diff") { - return Diff(args); - } else if (command == "optimize") { - return Optimize(args); - } else if (command == "convert") { - return Convert(args); - } else if (command == "version") { - PrintVersion(); + int Action(const std::vector<std::string>& /* args */) override { + std::cerr << StringPrintf("Android Asset Packaging Tool (aapt) %s:%s", sMajorVersion, + sMinorVersion) + << std::endl; return 0; } - diagnostics->Error(DiagMessage() << "unknown command '" << command << "'"); - return -1; -} +}; + +/** The main entry point of AAPT. */ +class MainCommand : public Command { + public: + explicit MainCommand(IDiagnostics* diagnostics) : Command("aapt2"), diagnostics_(diagnostics) { + AddOptionalSubcommand(util::make_unique<CompileCommand>(diagnostics)); + AddOptionalSubcommand(util::make_unique<LinkCommand>(diagnostics)); + AddOptionalSubcommand(util::make_unique<DumpCommand>()); + AddOptionalSubcommand(util::make_unique<DiffCommand>()); + AddOptionalSubcommand(util::make_unique<OptimizeCommand>()); + AddOptionalSubcommand(util::make_unique<ConvertCommand>()); + AddOptionalSubcommand(util::make_unique<VersionCommand>()); + } -static void RunDaemon(IDiagnostics* diagnostics) { - std::cout << "Ready" << std::endl; - - // Run in daemon mode. The first line of input is the command. This can be 'quit' which ends - // the daemon mode. Each subsequent line is a single parameter to the command. The end of a - // invocation is signaled by providing an empty line. At any point, an EOF signal or the - // command 'quit' will end the daemon mode. - while (true) { - std::vector<std::string> raw_args; - for (std::string line; std::getline(std::cin, line) && !line.empty();) { - raw_args.push_back(line); + int Action(const std::vector<std::string>& args) override { + if (args.size() == 0) { + diagnostics_->Error(DiagMessage() << "no subcommand specified"); + } else { + diagnostics_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'"); } - if (!std::cin) { - break; - } + Usage(&std::cerr); + return -1; + } - // An empty command does nothing. - if (raw_args.empty()) { - continue; - } + private: + IDiagnostics* diagnostics_; +}; - if (raw_args[0] == "quit") { - break; - } +/* + * Run in daemon mode. The first line of input is the command. This can be 'quit' which ends + * the daemon mode. Each subsequent line is a single parameter to the command. The end of a + * invocation is signaled by providing an empty line. At any point, an EOF signal or the + * command 'quit' will end the daemon mode. + */ +class DaemonCommand : public Command { + public: + explicit DaemonCommand(IDiagnostics* diagnostics) : Command("daemon", "m"), + diagnostics_(diagnostics) { + SetDescription("Runs aapt in daemon mode. Each subsequent line is a single parameter to the\n" + "command. The end of an invocation is signaled by providing an empty line."); + } - std::vector<StringPiece> args; - args.insert(args.end(), ++raw_args.begin(), raw_args.end()); - int ret = ExecuteCommand(raw_args[0], args, diagnostics); - if (ret != 0) { - std::cerr << "Error" << std::endl; + int Action(const std::vector<std::string>& /* args */) override { + std::cout << "Ready" << std::endl; + + while (true) { + std::vector<std::string> raw_args; + for (std::string line; std::getline(std::cin, line) && !line.empty();) { + raw_args.push_back(line); + } + + if (!std::cin) { + break; + } + + // An empty command does nothing. + if (raw_args.empty()) { + continue; + } + + // End the dameon + if (raw_args[0] == "quit") { + break; + } + + std::vector<StringPiece> args; + args.insert(args.end(), raw_args.begin(), raw_args.end()); + if (MainCommand(diagnostics_).Execute(args, &std::cerr) != 0) { + std::cerr << "Error" << std::endl; + } + std::cerr << "Done" << std::endl; } - std::cerr << "Done" << std::endl; + std::cout << "Exiting daemon" << std::endl; + + return 0; } - std::cout << "Exiting daemon" << std::endl; -} + + private: + IDiagnostics* diagnostics_; +}; } // namespace aapt int MainImpl(int argc, char** argv) { - if (argc < 2) { - std::cerr << "no command specified\n"; - aapt::PrintUsage(); + if (argc < 1) { return -1; } - argv += 1; - argc -= 1; - - aapt::StdErrDiagnostics diagnostics; - // Collect the arguments starting after the program name and command name. std::vector<StringPiece> args; for (int i = 1; i < argc; i++) { args.push_back(argv[i]); } - const StringPiece command(argv[0]); - if (command != "daemon" && command != "m") { - // Single execution. - const int result = aapt::ExecuteCommand(command, args, &diagnostics); - if (result < 0) { - aapt::PrintUsage(); - } - return result; - } + // Add the daemon subcommand here so it cannot be called while executing the daemon + aapt::StdErrDiagnostics diagnostics; + auto main_command = new aapt::MainCommand(&diagnostics); + main_command->AddOptionalSubcommand(aapt::util::make_unique<aapt::DaemonCommand>(&diagnostics)); - aapt::RunDaemon(&diagnostics); - return 0; + return main_command->Execute(args, &std::cerr); } int main(int argc, char** argv) { |