summaryrefslogtreecommitdiff
path: root/tools/aapt2/Main.cpp
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2017-11-14 12:31:11 -0800
committerXin Li <delphij@google.com>2017-11-14 12:31:11 -0800
commit220871a697290529278ed16db508eda8e12f3fc7 (patch)
treebc13101b63c6fe39a9d92706ecb7ded7f98f5a9c /tools/aapt2/Main.cpp
parent802f191b2b84a1b1b82c7f6f3268846084b35dfb (diff)
parent98e12851336b7db16e583f9afac63ecc97465980 (diff)
Merge commit '98e12851336b7db16e583f9afac63ecc97465980' from
oc-mr1-dev-plus-aosp-without-vendor into stage-aosp-master. Change-Id: Ia7b8da4a00d215160e4a4fa40f6044208d1297b7 Merged-In: I19846d2a3ee27aecbae2367a74ee49082eea154d
Diffstat (limited to 'tools/aapt2/Main.cpp')
-rw-r--r--tools/aapt2/Main.cpp172
1 files changed, 134 insertions, 38 deletions
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 1d2e3a4f2df0..36ab30c7fb6e 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -14,12 +14,26 @@
* limitations under the License.
*/
+#ifdef _WIN32
+// clang-format off
+#include <windows.h>
+#include <shellapi.h>
+// clang-format on
+#endif
+
#include <iostream>
#include <vector>
+#include "android-base/stringprintf.h"
+#include "android-base/utf8.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
+#include "util/Files.h"
+#include "util/Util.h"
+
+using ::android::StringPiece;
+using ::android::base::StringPrintf;
namespace aapt {
@@ -27,54 +41,136 @@ namespace aapt {
static const char* sMajorVersion = "2";
// Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "16";
+static const char* sMinorVersion = "19";
-int PrintVersion() {
- std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
- << sMinorVersion << std::endl;
- return 0;
+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|version] ..." << std::endl;
}
-extern int Compile(const std::vector<android::StringPiece>& args, IDiagnostics* diagnostics);
-extern int Link(const std::vector<android::StringPiece>& args, IDiagnostics* diagnostics);
-extern int Dump(const std::vector<android::StringPiece>& args);
-extern int Diff(const std::vector<android::StringPiece>& args);
-extern int Optimize(const std::vector<android::StringPiece>& args);
+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);
-} // namespace aapt
+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 == "version") {
+ PrintVersion();
+ return 0;
+ }
+ diagnostics->Error(DiagMessage() << "unknown command '" << command << "'");
+ return -1;
+}
-int main(int argc, char** argv) {
- if (argc >= 2) {
- argv += 1;
- argc -= 1;
+static void RunDaemon(IDiagnostics* diagnostics) {
+ std::cout << "Ready" << std::endl;
- std::vector<android::StringPiece> args;
- for (int i = 1; i < argc; i++) {
- args.push_back(argv[i]);
+ // 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);
}
- android::StringPiece command(argv[0]);
- if (command == "compile" || command == "c") {
- aapt::StdErrDiagnostics diagnostics;
- return aapt::Compile(args, &diagnostics);
- } else if (command == "link" || command == "l") {
- aapt::StdErrDiagnostics diagnostics;
- return aapt::Link(args, &diagnostics);
- } else if (command == "dump" || command == "d") {
- return aapt::Dump(args);
- } else if (command == "diff") {
- return aapt::Diff(args);
- } else if (command == "optimize") {
- return aapt::Optimize(args);
- } else if (command == "version") {
- return aapt::PrintVersion();
+ if (!std::cin) {
+ break;
}
- std::cerr << "unknown command '" << command << "'\n";
- } else {
+
+ // An empty command does nothing.
+ if (raw_args.empty()) {
+ continue;
+ }
+
+ if (raw_args[0] == "quit") {
+ break;
+ }
+
+ 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;
+ }
+ std::cerr << "Done" << std::endl;
+ }
+ std::cout << "Exiting daemon" << std::endl;
+}
+
+} // namespace aapt
+
+int MainImpl(int argc, char** argv) {
+ if (argc < 2) {
std::cerr << "no command specified\n";
+ aapt::PrintUsage();
+ return -1;
}
- std::cerr << "\nusage: aapt2 [compile|link|dump|diff|optimize|version] ..."
- << std::endl;
- 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;
+ }
+
+ aapt::RunDaemon(&diagnostics);
+ return 0;
+}
+
+int main(int argc, char** argv) {
+#ifdef _WIN32
+ LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ CHECK(wide_argv != nullptr) << "invalid command line parameters passed to process";
+
+ std::vector<std::string> utf8_args;
+ for (int i = 0; i < argc; i++) {
+ std::string utf8_arg;
+ if (!::android::base::WideToUTF8(wide_argv[i], &utf8_arg)) {
+ std::cerr << "error converting input arguments to UTF-8" << std::endl;
+ return 1;
+ }
+ utf8_args.push_back(std::move(utf8_arg));
+ }
+ LocalFree(wide_argv);
+
+ std::unique_ptr<char* []> utf8_argv(new char*[utf8_args.size()]);
+ for (int i = 0; i < argc; i++) {
+ utf8_argv[i] = const_cast<char*>(utf8_args[i].c_str());
+ }
+ argv = utf8_argv.get();
+#endif
+ return MainImpl(argc, argv);
}