1
2#include "options.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8static int
9usage()
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
34int
35parse_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