Clean up options parsing logic a little bit
We're about to add support for asking for C++ output.
Make this a little less tedious and flesh out the unittests a little.
Bug: 23599341
Test: unittests
Change-Id: Ie08414db43b48ae1a90640260b0badf4c4eb60f8
diff --git a/main.cpp b/main.cpp
index 7aba3fb..7fc4193 100644
--- a/main.cpp
+++ b/main.cpp
@@ -29,7 +29,7 @@
}
switch (options->task) {
- case Options::COMPILE_AIDL:
+ case Options::COMPILE_AIDL_TO_JAVA:
return android::aidl::compile_aidl(*options);
case Options::PREPROCESS_AIDL:
return android::aidl::preprocess_aidl(*options);
diff --git a/options.cpp b/options.cpp
index b4f4e54..d5aa21d 100644
--- a/options.cpp
+++ b/options.cpp
@@ -69,58 +69,55 @@
return options;
}
+ options->task = COMPILE_AIDL_TO_JAVA;
// OPTIONS
while (i < argc) {
const char* s = argv[i];
- int len = strlen(s);
- if (s[0] == '-') {
- if (len > 1) {
- // -I<system-import-path>
- if (s[1] == 'I') {
- if (len > 2) {
- options->import_paths_.push_back(s + 2);
- } else {
- fprintf(stderr, "-I option (%d) requires a path.\n", i);
- return usage();
- }
- } else if (s[1] == 'd') {
- if (len > 2) {
- options->dep_file_name_ = s + 2;
- } else {
- fprintf(stderr, "-d option (%d) requires a file.\n", i);
- return usage();
- }
- } else if (s[1] == 'a') {
- options->auto_dep_file_ = true;
- } else if (s[1] == 'p') {
- if (len > 2) {
- options->preprocessed_files_.push_back(s + 2);
- } else {
- fprintf(stderr, "-p option (%d) requires a file.\n", i);
- return usage();
- }
- } else if (s[1] == 'o') {
- if (len > 2) {
- options->output_base_folder_ = s + 2;
- } else {
- fprintf(stderr, "-o option (%d) requires a path.\n", i);
- return usage();
- }
- } else if (len == 2 && s[1] == 'b') {
- options->fail_on_parcelable_ = true;
- } else {
- // s[1] is not known
- fprintf(stderr, "unknown option (%d): %s\n", i, s);
- return usage();
- }
+ const size_t len = strlen(s);
+ if (s[0] != '-') {
+ break;
+ }
+ if (len <= 1) {
+ fprintf(stderr, "unknown option (%d): %s\n", i, s);
+ return usage();
+ }
+ // -I<system-import-path>
+ if (s[1] == 'I') {
+ if (len > 2) {
+ options->import_paths_.push_back(s + 2);
} else {
- // len <= 1
- fprintf(stderr, "unknown option (%d): %s\n", i, s);
+ fprintf(stderr, "-I option (%d) requires a path.\n", i);
return usage();
}
+ } else if (s[1] == 'd') {
+ if (len > 2) {
+ options->dep_file_name_ = s + 2;
+ } else {
+ fprintf(stderr, "-d option (%d) requires a file.\n", i);
+ return usage();
+ }
+ } else if (strcmp(s, "-a") == 0) {
+ options->auto_dep_file_ = true;
+ } else if (s[1] == 'p') {
+ if (len > 2) {
+ options->preprocessed_files_.push_back(s + 2);
+ } else {
+ fprintf(stderr, "-p option (%d) requires a file.\n", i);
+ return usage();
+ }
+ } else if (s[1] == 'o') {
+ if (len > 2) {
+ options->output_base_folder_= s + 2;
+ } else {
+ fprintf(stderr, "-o option (%d) requires a path.\n", i);
+ return usage();
+ }
+ } else if (strcmp(s, "-b") == 0) {
+ options->fail_on_parcelable_ = true;
} else {
- // s[0] != '-'
- break;
+ // s[1] is not known
+ fprintf(stderr, "unknown option (%d): %s\n", i, s);
+ return usage();
}
i++;
}
@@ -138,7 +135,7 @@
if (i < argc) {
options->output_file_name_ = argv[i];
i++;
- } else if (options->output_base_folder_.length() == 0) {
+ } else if (options->output_base_folder_.empty()) {
// copy input into output and change the extension from .aidl to .java
options->output_file_name_= options->input_file_name_;
const size_t suffix_len = 5; // 5 = strlen(".aidl")
diff --git a/options.h b/options.h
index 018345e..c8ac8a8 100644
--- a/options.h
+++ b/options.h
@@ -31,8 +31,8 @@
class Options {
public:
enum {
- COMPILE_AIDL,
- PREPROCESS_AIDL
+ COMPILE_AIDL_TO_JAVA,
+ PREPROCESS_AIDL,
};
~Options() = default;
@@ -43,7 +43,7 @@
static std::unique_ptr<Options> ParseOptions(int argc,
const char* const* argv);
- int task{COMPILE_AIDL};
+ int task{COMPILE_AIDL_TO_JAVA};
bool fail_on_parcelable_{false};
std::vector<std::string> import_paths_;
std::vector<std::string> preprocessed_files_;
diff --git a/options_unittest.cpp b/options_unittest.cpp
index 732bfea..31c4ced 100644
--- a/options_unittest.cpp
+++ b/options_unittest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <iostream>
#include <string>
#include <vector>
@@ -21,6 +22,8 @@
#include "options.h"
+using std::cerr;
+using std::endl;
using std::string;
using std::unique_ptr;
using std::vector;
@@ -39,25 +42,62 @@
kPreprocessCommandInput1,
kPreprocessCommandInput2,
kPreprocessCommandInput3,
+ nullptr,
};
+const char kCompileCommandInput[] = "input.aidl";
+const char kCompileCommandIncludePath[] = "-Iinclude_path";
+const char* kCompileJavaCommand[] = {
+ "aidl",
+ "-b",
+ kCompileCommandIncludePath,
+ kCompileCommandInput,
+ nullptr,
+};
+const char kCompileCommandOutput[] = "input.java";
+
+unique_ptr<Options> GetOptions(const char* command[]) {
+ int argc = 0;
+ const char** command_part = command;
+ for (; *command_part; ++argc, ++command_part) {}
+ unique_ptr<Options> options(Options::ParseOptions(argc, command));
+ if (!options) {
+ cerr << "Failed to parse command line:";
+ for (int i = 0; i < argc; ++i) {
+ cerr << " " << command[i];
+ cerr << endl;
+ }
+ }
+ EXPECT_NE(options, nullptr) << "Failed to parse options!";
+ return options;
+}
+
} // namespace
TEST(OptionsTests, ParsesPreprocess) {
- const int argc = sizeof(kPreprocessCommand) / sizeof(*kPreprocessCommand);
- unique_ptr<Options> options(Options::ParseOptions(argc, kPreprocessCommand));
- EXPECT_NE(options, nullptr);
- EXPECT_EQ(options->task, Options::PREPROCESS_AIDL);
- EXPECT_EQ(options->fail_on_parcelable_, false);
- EXPECT_EQ(options->import_paths_.size(), 0u);
- EXPECT_EQ(options->preprocessed_files_.size(), 0u);
- EXPECT_EQ(options->input_file_name_, string{});
- EXPECT_EQ(options->output_file_name_, string{kPreprocessCommandOutputFile});
- EXPECT_EQ(options->auto_dep_file_, false);
+ unique_ptr<Options> options = GetOptions(kPreprocessCommand);
+ EXPECT_EQ(Options::PREPROCESS_AIDL, options->task);
+ EXPECT_EQ(false, options->fail_on_parcelable_);
+ EXPECT_EQ(0u, options->import_paths_.size());
+ EXPECT_EQ(0u, options->preprocessed_files_.size());
+ EXPECT_EQ(string{}, options->input_file_name_);
+ EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->output_file_name_);
+ EXPECT_EQ(false, options->auto_dep_file_);
const vector<string> expected_input{kPreprocessCommandInput1,
kPreprocessCommandInput2,
kPreprocessCommandInput3};
- EXPECT_EQ(options->files_to_preprocess_, expected_input);
+ EXPECT_EQ(expected_input, options->files_to_preprocess_);
+}
+
+TEST(OptionsTests, ParsesCompileJava) {
+ unique_ptr<Options> options = GetOptions(kCompileJavaCommand);
+ EXPECT_EQ(Options::COMPILE_AIDL_TO_JAVA, options->task);
+ EXPECT_EQ(true, options->fail_on_parcelable_);
+ EXPECT_EQ(1u, options->import_paths_.size());
+ EXPECT_EQ(0u, options->preprocessed_files_.size());
+ EXPECT_EQ(string{kCompileCommandInput}, options->input_file_name_);
+ EXPECT_EQ(string{kCompileCommandOutput}, options->output_file_name_);
+ EXPECT_EQ(false, options->auto_dep_file_);
}
} // namespace android