Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015, The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 16 | |
| 17 | #include "options.h" |
| 18 | |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 19 | #include <cstring> |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 20 | #include <iostream> |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 21 | #include <stdio.h> |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 22 | |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 23 | #include "logging.h" |
| 24 | #include "os.h" |
| 25 | |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 26 | using std::cerr; |
| 27 | using std::endl; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 28 | using std::string; |
| 29 | using std::unique_ptr; |
Christopher Wiley | eb1acc1 | 2015-09-16 11:25:13 -0700 | [diff] [blame] | 30 | using std::vector; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 31 | |
| 32 | namespace android { |
| 33 | namespace aidl { |
| 34 | namespace { |
| 35 | |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 36 | unique_ptr<JavaOptions> java_usage() { |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 37 | fprintf(stderr, |
| 38 | "usage: aidl OPTIONS INPUT [OUTPUT]\n" |
| 39 | " aidl --preprocess OUTPUT INPUT...\n" |
| 40 | "\n" |
| 41 | "OPTIONS:\n" |
| 42 | " -I<DIR> search path for import statements.\n" |
| 43 | " -d<FILE> generate dependency file.\n" |
| 44 | " -a generate dependency file next to the output file with " |
| 45 | "the name based on the input file.\n" |
| 46 | " -p<FILE> file created by --preprocess to import.\n" |
| 47 | " -o<FOLDER> base output folder for generated files.\n" |
| 48 | " -b fail when trying to compile a parcelable.\n" |
| 49 | "\n" |
| 50 | "INPUT:\n" |
| 51 | " An aidl interface file.\n" |
| 52 | "\n" |
| 53 | "OUTPUT:\n" |
| 54 | " The generated interface files.\n" |
| 55 | " If omitted and the -o option is not used, the input filename is " |
| 56 | "used, with the .aidl extension changed to a .java extension.\n" |
| 57 | " If the -o option is used, the generated files will be placed in " |
| 58 | "the base output folder, under their package folder\n"); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 59 | return unique_ptr<JavaOptions>(nullptr); |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 60 | } |
| 61 | |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 62 | } // namespace |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 63 | |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 64 | unique_ptr<JavaOptions> JavaOptions::Parse(int argc, const char* const* argv) { |
| 65 | unique_ptr<JavaOptions> options(new JavaOptions()); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 66 | int i = 1; |
| 67 | |
| 68 | if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) { |
| 69 | if (argc < 4) { |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 70 | return java_usage(); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 71 | } |
Christopher Wiley | 8f8cc9b | 2015-09-14 13:47:40 -0700 | [diff] [blame] | 72 | options->output_file_name_ = argv[2]; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 73 | for (int i = 3; i < argc; i++) { |
Christopher Wiley | 8f8cc9b | 2015-09-14 13:47:40 -0700 | [diff] [blame] | 74 | options->files_to_preprocess_.push_back(argv[i]); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 75 | } |
| 76 | options->task = PREPROCESS_AIDL; |
| 77 | return options; |
| 78 | } |
| 79 | |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 80 | options->task = COMPILE_AIDL_TO_JAVA; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 81 | // OPTIONS |
| 82 | while (i < argc) { |
| 83 | const char* s = argv[i]; |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 84 | const size_t len = strlen(s); |
| 85 | if (s[0] != '-') { |
| 86 | break; |
| 87 | } |
| 88 | if (len <= 1) { |
| 89 | fprintf(stderr, "unknown option (%d): %s\n", i, s); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 90 | return java_usage(); |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 91 | } |
| 92 | // -I<system-import-path> |
| 93 | if (s[1] == 'I') { |
| 94 | if (len > 2) { |
| 95 | options->import_paths_.push_back(s + 2); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 96 | } else { |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 97 | fprintf(stderr, "-I option (%d) requires a path.\n", i); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 98 | return java_usage(); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 99 | } |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 100 | } else if (s[1] == 'd') { |
| 101 | if (len > 2) { |
| 102 | options->dep_file_name_ = s + 2; |
| 103 | } else { |
| 104 | fprintf(stderr, "-d option (%d) requires a file.\n", i); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 105 | return java_usage(); |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 106 | } |
| 107 | } else if (strcmp(s, "-a") == 0) { |
| 108 | options->auto_dep_file_ = true; |
| 109 | } else if (s[1] == 'p') { |
| 110 | if (len > 2) { |
| 111 | options->preprocessed_files_.push_back(s + 2); |
| 112 | } else { |
| 113 | fprintf(stderr, "-p option (%d) requires a file.\n", i); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 114 | return java_usage(); |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 115 | } |
| 116 | } else if (s[1] == 'o') { |
| 117 | if (len > 2) { |
| 118 | options->output_base_folder_= s + 2; |
| 119 | } else { |
| 120 | fprintf(stderr, "-o option (%d) requires a path.\n", i); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 121 | return java_usage(); |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 122 | } |
| 123 | } else if (strcmp(s, "-b") == 0) { |
| 124 | options->fail_on_parcelable_ = true; |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 125 | } else { |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 126 | // s[1] is not known |
| 127 | fprintf(stderr, "unknown option (%d): %s\n", i, s); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 128 | return java_usage(); |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 129 | } |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 130 | i++; |
| 131 | } |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 132 | // INPUT |
| 133 | if (i < argc) { |
Christopher Wiley | 8f8cc9b | 2015-09-14 13:47:40 -0700 | [diff] [blame] | 134 | options->input_file_name_ = argv[i]; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 135 | i++; |
| 136 | } else { |
| 137 | fprintf(stderr, "INPUT required\n"); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 138 | return java_usage(); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 139 | } |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 140 | if (!EndsWith(options->input_file_name_, ".aidl")) { |
| 141 | cerr << "Expected .aidl file for input but got " |
| 142 | << options->input_file_name_ << endl; |
| 143 | return java_usage(); |
| 144 | } |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 145 | |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 146 | // OUTPUT |
| 147 | if (i < argc) { |
Christopher Wiley | 8f8cc9b | 2015-09-14 13:47:40 -0700 | [diff] [blame] | 148 | options->output_file_name_ = argv[i]; |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 149 | i++; |
Christopher Wiley | d93c5b7 | 2015-09-14 13:21:37 -0700 | [diff] [blame] | 150 | } else if (options->output_base_folder_.empty()) { |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 151 | // copy input into output and change the extension from .aidl to .java |
Christopher Wiley | 8f8cc9b | 2015-09-14 13:47:40 -0700 | [diff] [blame] | 152 | options->output_file_name_= options->input_file_name_; |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 153 | if (!ReplaceSuffix(".aidl", ".java", &options->output_file_name_)) { |
| 154 | // we should never get here since we validated the suffix. |
| 155 | LOG(FATAL) << "Internal aidl error."; |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 156 | return java_usage(); |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 157 | } |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 158 | } |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 159 | |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 160 | // anything remaining? |
| 161 | if (i != argc) { |
| 162 | fprintf(stderr, "unknown option%s:", |
| 163 | (i == argc - 1 ? (const char*)"" : (const char*)"s")); |
| 164 | for (; i < argc - 1; i++) { |
| 165 | fprintf(stderr, " %s", argv[i]); |
| 166 | } |
| 167 | fprintf(stderr, "\n"); |
Christopher Wiley | 89eaab5 | 2015-09-15 14:46:46 -0700 | [diff] [blame] | 168 | return java_usage(); |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | return options; |
Adam Lesinski | ffa1686 | 2014-01-23 18:17:42 -0800 | [diff] [blame] | 172 | } |
| 173 | |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 174 | namespace { |
| 175 | |
| 176 | unique_ptr<CppOptions> cpp_usage() { |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 177 | cerr << "usage: aidl-cpp INPUT_FILE HEADER_DIR OUTPUT_FILE" << endl |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 178 | << endl |
| 179 | << "OPTIONS:" << endl |
| 180 | << " -I<DIR> search path for import statements" << endl |
| 181 | << " -d<FILE> generate dependency file" << endl |
| 182 | << endl |
| 183 | << "INPUT_FILE:" << endl |
| 184 | << " an aidl interface file" << endl |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 185 | << "HEADER_DIR:" << endl |
| 186 | << " empty directory to put generated headers" << endl |
| 187 | << "OUTPUT_FILE:" << endl |
| 188 | << " path to write generated .cpp code" << endl; |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 189 | return unique_ptr<CppOptions>(nullptr); |
| 190 | } |
| 191 | |
| 192 | } // namespace |
| 193 | |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 194 | unique_ptr<CppOptions> CppOptions::Parse(int argc, const char* const* argv) { |
| 195 | unique_ptr<CppOptions> options(new CppOptions()); |
| 196 | int i = 1; |
| 197 | |
| 198 | // Parse flags, all of which start with '-' |
| 199 | for ( ; i < argc; ++i) { |
| 200 | const size_t len = strlen(argv[i]); |
| 201 | const char *s = argv[i]; |
| 202 | if (s[0] != '-') { |
| 203 | break; // On to the positional arguments. |
| 204 | } |
| 205 | if (len < 2) { |
| 206 | cerr << "Invalid argument '" << s << "'." << endl; |
| 207 | return cpp_usage(); |
| 208 | } |
| 209 | const string the_rest = s + 2; |
| 210 | if (s[1] == 'I') { |
| 211 | options->import_paths_.push_back(the_rest); |
| 212 | } else if (s[1] == 'd') { |
| 213 | options->dep_file_name_ = the_rest; |
| 214 | } else { |
| 215 | cerr << "Invalid argument '" << s << "'." << endl; |
| 216 | return cpp_usage(); |
| 217 | } |
| 218 | } |
| 219 | |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 220 | // There are exactly three positional arguments. |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 221 | const int remaining_args = argc - i; |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 222 | if (remaining_args != 3) { |
| 223 | cerr << "Expected 3 positional arguments but got " << remaining_args << "." << endl; |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 224 | return cpp_usage(); |
| 225 | } |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 226 | |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 227 | options->input_file_name_ = argv[i]; |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 228 | options->output_header_dir_ = argv[i + 1]; |
| 229 | options->output_file_name_ = argv[i + 2]; |
| 230 | |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 231 | if (!EndsWith(options->input_file_name_, ".aidl")) { |
Christopher Wiley | 054afbd | 2015-10-16 17:08:43 -0700 | [diff] [blame^] | 232 | cerr << "Expected .aidl file for input but got " << options->input_file_name_ << endl; |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 233 | return cpp_usage(); |
| 234 | } |
| 235 | |
Christopher Wiley | a590de8 | 2015-09-15 15:46:28 -0700 | [diff] [blame] | 236 | return options; |
| 237 | } |
| 238 | |
Christopher Wiley | 4432ccf | 2015-09-18 18:32:08 -0700 | [diff] [blame] | 239 | bool EndsWith(const string& str, const string& suffix) { |
| 240 | if (str.length() < suffix.length()) { |
| 241 | return false; |
| 242 | } |
| 243 | return std::equal(str.crbegin(), str.crbegin() + suffix.length(), |
| 244 | suffix.crbegin()); |
| 245 | } |
| 246 | |
| 247 | bool ReplaceSuffix(const string& old_suffix, |
| 248 | const string& new_suffix, |
| 249 | string* str) { |
| 250 | if (!EndsWith(*str, old_suffix)) return false; |
| 251 | str->replace(str->length() - old_suffix.length(), |
| 252 | old_suffix.length(), |
| 253 | new_suffix); |
| 254 | return true; |
| 255 | } |
| 256 | |
| 257 | |
| 258 | |
Christopher Wiley | 4427d86 | 2015-09-14 11:07:39 -0700 | [diff] [blame] | 259 | } // namespace android |
| 260 | } // namespace aidl |