1 
2 #include "options.h"
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 static int
usage()9 usage()
10 {
11     fprintf(stderr,
12             "usage: aidl OPTIONS INPUT [OUTPUT]\n"
13             "       aidl --preprocess OUTPUT INPUT...\n"
14             "\n"
15             "OPTIONS:\n"
16             "   -I<DIR>    search path for import statements.\n"
17             "   -d<FILE>   generate dependency file.\n"
18             "   -a         generate dependency file next to the output file with the name based on the input file.\n"
19             "   -p<FILE>   file created by --preprocess to import.\n"
20             "   -o<FOLDER> base output folder for generated files.\n"
21             "   -b         fail when trying to compile a parcelable.\n"
22             "\n"
23             "INPUT:\n"
24             "   An aidl interface file.\n"
25             "\n"
26             "OUTPUT:\n"
27             "   The generated interface files.\n"
28             "   If omitted and the -o option is not used, the input filename is used, with the .aidl extension changed to a .java extension.\n"
29             "   If the -o option is used, the generated files will be placed in the base output folder, under their package folder\n"
30            );
31     return 1;
32 }
33 
34 int
parse_options(int argc,const char * const * argv,Options * options)35 parse_options(int argc, const char* const* argv, Options *options)
36 {
37     int i = 1;
38 
39     if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) {
40         if (argc < 4) {
41             return usage();
42         }
43         options->outputFileName = argv[2];
44         for (int i=3; i<argc; i++) {
45             options->filesToPreprocess.push_back(argv[i]);
46         }
47         options->task = PREPROCESS_AIDL;
48         return 0;
49     }
50 
51     options->task = COMPILE_AIDL;
52     options->failOnParcelable = false;
53     options->autoDepFile = false;
54 
55     // OPTIONS
56     while (i < argc) {
57         const char* s = argv[i];
58         int len = strlen(s);
59         if (s[0] == '-') {
60             if (len > 1) {
61                 // -I<system-import-path>
62                 if (s[1] == 'I') {
63                     if (len > 2) {
64                         options->importPaths.push_back(s+2);
65                     } else {
66                         fprintf(stderr, "-I option (%d) requires a path.\n", i);
67                         return usage();
68                     }
69                 }
70                 else if (s[1] == 'd') {
71                     if (len > 2) {
72                         options->depFileName = s+2;
73                     } else {
74                         fprintf(stderr, "-d option (%d) requires a file.\n", i);
75                         return usage();
76                     }
77                 }
78                 else if (s[1] == 'a') {
79                     options->autoDepFile = true;
80                 }
81                 else if (s[1] == 'p') {
82                     if (len > 2) {
83                         options->preprocessedFiles.push_back(s+2);
84                     } else {
85                         fprintf(stderr, "-p option (%d) requires a file.\n", i);
86                         return usage();
87                     }
88                 }
89                 else if (s[1] == 'o') {
90                     if (len > 2) {
91                         options->outputBaseFolder = s+2;
92                     } else {
93                         fprintf(stderr, "-o option (%d) requires a path.\n", i);
94                         return usage();
95                     }
96                 }
97                 else if (len == 2 && s[1] == 'b') {
98                     options->failOnParcelable = true;
99                 }
100                 else {
101                     // s[1] is not known
102                     fprintf(stderr, "unknown option (%d): %s\n", i, s);
103                     return usage();
104                 }
105             } else {
106                 // len <= 1
107                 fprintf(stderr, "unknown option (%d): %s\n", i, s);
108                 return usage();
109             }
110         } else {
111             // s[0] != '-'
112             break;
113         }
114         i++;
115     }
116 
117     // INPUT
118     if (i < argc) {
119         options->inputFileName = argv[i];
120         i++;
121     } else {
122         fprintf(stderr, "INPUT required\n");
123         return usage();
124     }
125 
126     // OUTPUT
127     if (i < argc) {
128         options->outputFileName = argv[i];
129         i++;
130     } else if (options->outputBaseFolder.length() == 0) {
131         // copy input into output and change the extension from .aidl to .java
132         options->outputFileName = options->inputFileName;
133         string::size_type pos = options->outputFileName.size()-5;
134         if (options->outputFileName.compare(pos, 5, ".aidl") == 0) {  // 5 = strlen(".aidl")
135             options->outputFileName.replace(pos, 5, ".java"); // 5 = strlen(".aidl")
136         } else {
137             fprintf(stderr, "INPUT is not an .aidl file.\n");
138             return usage();
139         }
140      }
141 
142     // anything remaining?
143     if (i != argc) {
144         fprintf(stderr, "unknown option%s:", (i==argc-1?(const char*)"":(const char*)"s"));
145         for (; i<argc-1; i++) {
146             fprintf(stderr, " %s", argv[i]);
147         }
148         fprintf(stderr, "\n");
149         return usage();
150     }
151 
152     return 0;
153 }
154 
155