1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "aidl_language.h"
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "options.h"
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "search_path.h"
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Type.h"
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "generate_java.h"
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <unistd.h>
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <fcntl.h>
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/param.h>
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/stat.h>
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h>
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdlib.h>
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <string.h>
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <map>
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_MS_C_RUNTIME
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <io.h>
19c9d32390e59d99c76b79edd247a1127088ce81ecAndrew Hsieh#include <direct.h>
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <sys/stat.h>
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef O_BINARY
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#  define O_BINARY  0
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The following are gotten as the offset from the allowable id's between
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define MIN_USER_SET_METHOD_ID                0
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define MAX_USER_SET_METHOD_ID                16777214
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace std;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskitest_document(document_item_type* d)
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (d) {
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (d->item_type == INTERFACE_TYPE_BINDER) {
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* c = (interface_type*)d;
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            printf("interface %s %s {\n", c->package, c->name.data);
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_item_type *q = (interface_item_type*)c->interface_items;
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            while (q) {
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (q->item_type == METHOD_TYPE) {
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    method_type *m = (method_type*)q;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    printf("  %s %s(", m->type.type.data, m->name.data);
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg_type *p = m->args;
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    while (p) {
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        printf("%s %s",p->type.type.data,p->name.data);
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        if (p->next) printf(", ");
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        p=p->next;
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    printf(")");
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    printf(";\n");
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                q=q->next;
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            printf("}\n");
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (d->item_type == USER_DATA_TYPE) {
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* b = (user_data_type*)d;
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                printf("parcelable %s %s;\n", b->package, b->name.data);
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if ((b->flattening_methods & RPC_DATA) != 0) {
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                printf("flattenable %s %s;\n", b->package, b->name.data);
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else {
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        d = d->next;
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconvert_direction(const char* direction)
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (direction == NULL) {
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return IN_PARAMETER;
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (0 == strcmp(direction, "in")) {
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return IN_PARAMETER;
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (0 == strcmp(direction, "out")) {
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OUT_PARAMETER;
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return INOUT_PARAMETER;
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct import_info {
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* from;
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* filename;
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    buffer_type statement;
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* neededClass;
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    document_item_type* doc;
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    struct import_info* next;
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskidocument_item_type* g_document = NULL;
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport_info* g_imports = NULL;
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskimain_document_parsed(document_item_type* d)
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    g_document = d;
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskimain_import_parsed(buffer_type* statement)
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import_info* import = (import_info*)malloc(sizeof(import_info));
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    memset(import, 0, sizeof(import_info));
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->from = strdup(g_currentFilename);
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->statement.lineno = statement->lineno;
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->statement.data = strdup(statement->data);
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->statement.extra = NULL;
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->next = g_imports;
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import->neededClass = parse_import_statement(statement->data);
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    g_imports = import;
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic ParserCallbacks g_mainCallbacks = {
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    &main_document_parsed,
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    &main_import_parsed
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskichar*
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiparse_import_statement(const char* text)
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* end;
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int len;
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (isspace(*text)) {
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        text++;
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (!isspace(*text)) {
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        text++;
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (isspace(*text)) {
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        text++;
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    end = text;
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (!isspace(*end) && *end != ';') {
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        end++;
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    len = end-text;
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char* rv = (char*)malloc(len+1);
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    memcpy(rv, text, len);
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    rv[len] = '\0';
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return rv;
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport_import_parsed(buffer_type* statement)
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic ParserCallbacks g_importCallbacks = {
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    &main_document_parsed,
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    &import_import_parsed
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_filename(const char* filename, const char* package, buffer_type* name)
172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* p;
174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    string expected;
175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    string fn;
176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    size_t len;
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char cwd[MAXPATHLEN];
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool valid = false;
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_WINDOWS_PATHS
181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (isalpha(filename[0]) && filename[1] == ':'
182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        && filename[2] == OS_PATH_SEPARATOR) {
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (filename[0] == OS_PATH_SEPARATOR) {
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fn = filename;
187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fn = getcwd(cwd, sizeof(cwd));
189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        len = fn.length();
190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (fn[len-1] != OS_PATH_SEPARATOR) {
191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fn += OS_PATH_SEPARATOR;
192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fn += filename;
194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (package) {
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        expected = package;
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        expected += '.';
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    len = expected.length();
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i=0; i<len; i++) {
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (expected[i] == '.') {
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            expected[i] = OS_PATH_SEPARATOR;
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    p = strchr(name->data, '.');
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    len = p ? p-name->data : strlen(name->data);
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    expected.append(name->data, len);
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    expected += ".aidl";
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    len = fn.length();
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    valid = (len >= expected.length());
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (valid) {
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        p = fn.c_str() + (len - expected.length());
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_WINDOWS_PATHS
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (OS_PATH_SEPARATOR != '/') {
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Input filename under cygwin most likely has / separators
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // whereas the expected string uses \\ separators. Adjust
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // them accordingly.
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski          for (char *c = const_cast<char *>(p); *c; ++c) {
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (*c == '/') *c = OS_PATH_SEPARATOR;
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef OS_CASE_SENSITIVE
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        valid = (expected == p);
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        valid = !strcasecmp(expected.c_str(), p);
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!valid) {
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d interface %s should be declared in a file"
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                " called %s.\n",
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                filename, name->lineno, name->data, expected.c_str());
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 0;
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_filenames(const char* filename, document_item_type* items)
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err = 0;
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (items) {
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (items->item_type == USER_DATA_TYPE) {
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* p = (user_data_type*)items;
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err |= check_filename(filename, p->package, &p->name);
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (items->item_type == INTERFACE_TYPE_BINDER
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                || items->item_type == INTERFACE_TYPE_RPC) {
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* c = (interface_type*)items;
260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err |= check_filename(filename, c->package, &c->name);
261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else {
263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "aidl: internal error unkown document type %d.\n",
264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        items->item_type);
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 1;
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        items = items->next;
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char*
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskikind_to_string(int kind)
275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (kind)
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case Type::INTERFACE:
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return "an interface";
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case Type::USERDATA:
281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return "a user data";
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        default:
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return "ERROR";
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic char*
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskirfind(char* str, char c)
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char* p = str + strlen(str) - 1;
291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (p >= str) {
292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (*p == c) {
293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return p;
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        p--;
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return NULL;
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigather_types(const char* filename, document_item_type* items)
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err = 0;
304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (items) {
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Type* type;
306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (items->item_type == USER_DATA_TYPE) {
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* p = (user_data_type*)items;
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            type = new UserDataType(p->package ? p->package : "", p->name.data,
309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (items->item_type == INTERFACE_TYPE_BINDER
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                || items->item_type == INTERFACE_TYPE_RPC) {
314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* c = (interface_type*)items;
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            type = new InterfaceType(c->package ? c->package : "",
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            c->name.data, false, c->oneway,
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, c->name.lineno);
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else {
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "aidl: internal error %s:%d\n", __FILE__, __LINE__);
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 1;
322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Type* old = NAMES.Find(type->QualifiedName());
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (old == NULL) {
326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NAMES.Add(type);
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (items->item_type == INTERFACE_TYPE_BINDER) {
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // for interfaces, also add the stub and proxy types, we don't
330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // bother checking these for duplicates, because the parser
331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // won't let us do it.
332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                interface_type* c = (interface_type*)items;
333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                string name = c->name.data;
335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                name += ".Stub";
336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Type* stub = new Type(c->package ? c->package : "",
337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        name, Type::GENERATED, false, false, false,
338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        filename, c->name.lineno);
339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                NAMES.Add(stub);
340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                name = c->name.data;
342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                name += ".Stub.Proxy";
343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Type* proxy = new Type(c->package ? c->package : "",
344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        name, Type::GENERATED, false, false, false,
345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        filename, c->name.lineno);
346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                NAMES.Add(proxy);
347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            else if (items->item_type == INTERFACE_TYPE_RPC) {
349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // for interfaces, also add the service base type, we don't
350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // bother checking these for duplicates, because the parser
351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // won't let us do it.
352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                interface_type* c = (interface_type*)items;
353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                string name = c->name.data;
355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                name += ".ServiceBase";
356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Type* base = new Type(c->package ? c->package : "",
357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        name, Type::GENERATED, false, false, false,
358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                        filename, c->name.lineno);
359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                NAMES.Add(base);
360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (old->Kind() == Type::BUILT_IN) {
363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                fprintf(stderr, "%s:%d attempt to redefine built in class %s\n",
364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, type->DeclLine(),
365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            type->QualifiedName().c_str());
366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                err = 1;
367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            else if (type->Kind() != old->Kind()) {
369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                const char* oldKind = kind_to_string(old->Kind());
370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                const char* newKind = kind_to_string(type->Kind());
371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                fprintf(stderr, "%s:%d attempt to redefine %s as %s,\n",
373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, type->DeclLine(),
374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            type->QualifiedName().c_str(), newKind);
375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                fprintf(stderr, "%s:%d    previously defined here as %s.\n",
376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            old->DeclFile().c_str(), old->DeclLine(), oldKind);
377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                err = 1;
378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        items = items->next;
382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool
388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskimatches_keyword(const char* str)
389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    static const char* KEYWORDS[] = { "abstract", "assert", "boolean", "break",
391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "byte", "case", "catch", "char", "class", "const", "continue",
392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "default", "do", "double", "else", "enum", "extends", "final",
393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "finally", "float", "for", "goto", "if", "implements", "import",
394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "instanceof", "int", "interface", "long", "native", "new", "package",
395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "private", "protected", "public", "return", "short", "static",
396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "strictfp", "super", "switch", "synchronized", "this", "throw",
397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "throws", "transient", "try", "void", "volatile", "while",
398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "true", "false", "null",
399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        NULL
400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    };
401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char** k = KEYWORDS;
402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (*k) {
403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (0 == strcmp(str, *k)) {
404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return true;
405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        k++;
407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return false;
409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_method(const char* filename, int kind, method_type* m)
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err = 0;
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // return type
417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Type* returnType = NAMES.Search(m->type.type.data);
418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (returnType == NULL) {
419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d unknown return type %s\n", filename,
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    m->type.type.lineno, m->type.type.data);
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = 1;
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (returnType == EVENT_FAKE_TYPE) {
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (kind != INTERFACE_TYPE_RPC) {
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d event methods only supported for rpc interfaces\n",
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename, m->type.type.lineno);
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    : returnType->CanWriteToRpcData())) {
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        m->type.type.lineno, m->type.type.data);
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (m->type.dimension > 0 && !returnType->CanBeArray()) {
441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d return type %s%s can't be an array.\n", filename,
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                m->type.array_token.lineno, m->type.type.data,
443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                m->type.array_token.data);
444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = 1;
445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (m->type.dimension > 1) {
448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d return type %s%s only one"
449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                " dimensional arrays are supported\n", filename,
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                m->type.array_token.lineno, m->type.type.data,
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                m->type.array_token.data);
452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = 1;
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int index = 1;
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    arg_type* arg = m->args;
458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (arg) {
459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Type* t = NAMES.Search(arg->type.type.data);
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // check the arg type
462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (t == NULL) {
463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %s (%d) unknown type %s\n",
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename, m->type.type.lineno, arg->name.data, index,
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->type.type.data);
466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            goto next;
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (t == EVENT_FAKE_TYPE) {
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %s (%d) event can not be used as a parameter %s\n",
472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename, m->type.type.lineno, arg->name.data, index,
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->type.type.data);
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            goto next;
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        filename, m->type.type.lineno, index,
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        arg->type.type.data, arg->name.data);
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (returnType == EVENT_FAKE_TYPE
486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && convert_direction(arg->direction.data) != IN_PARAMETER) {
487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s' All paremeters on events must be 'in'.\n",
488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename, m->type.type.lineno, index,
489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->type.type.data, arg->name.data);
490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            goto next;
492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (arg->direction.data == NULL
495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && (arg->type.dimension != 0 || t->CanBeOutParameter())) {
496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out"
497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                " parameter, so you must declare it as in,"
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                " out or inout.\n",
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        filename, m->type.type.lineno, index,
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        arg->type.type.data, arg->name.data);
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (convert_direction(arg->direction.data) != IN_PARAMETER
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && !t->CanBeOutParameter()
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && arg->type.dimension == 0) {
507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s %s' can only be an in"
508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            " parameter.\n",
509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        filename, m->type.type.lineno, index,
510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        arg->direction.data, arg->type.type.data,
511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        arg->name.data);
512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (arg->type.dimension > 0 && !t->CanBeArray()) {
516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' can't be an"
517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    " array.\n", filename,
518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    m->type.array_token.lineno, index, arg->direction.data,
519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->type.type.data, arg->type.array_token.data,
520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->name.data);
521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (arg->type.dimension > 1) {
525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' only one"
526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    " dimensional arrays are supported\n", filename,
527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    m->type.array_token.lineno, index, arg->direction.data,
528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->type.type.data, arg->type.array_token.data,
529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    arg->name.data);
530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // check that the name doesn't match a keyword
534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (matches_keyword(arg->name.data)) {
535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d parameter %d %s is named the same as a"
536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    " Java or aidl keyword\n",
537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename, m->name.lineno, index, arg->name.data);
538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            err = 1;
539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskinext:
542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        index++;
543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        arg = arg->next;
544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_types(const char* filename, document_item_type* items)
551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err = 0;
553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (items) {
554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // (nothing to check for USER_DATA_TYPE)
555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (items->item_type == INTERFACE_TYPE_BINDER
556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                || items->item_type == INTERFACE_TYPE_RPC) {
557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            map<string,method_type*> methodNames;
558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* c = (interface_type*)items;
559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_item_type* member = c->interface_items;
561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            while (member) {
562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (member->item_type == METHOD_TYPE) {
563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    method_type* m = (method_type*)member;
564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    err |= check_method(filename, items->item_type, m);
566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // prevent duplicate methods
568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (methodNames.find(m->name.data) == methodNames.end()) {
569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        methodNames[m->name.data] = m;
570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } else {
571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        fprintf(stderr,"%s:%d attempt to redefine method %s,\n",
572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                filename, m->name.lineno, m->name.data);
573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        method_type* old = methodNames[m->name.data];
574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        fprintf(stderr, "%s:%d    previously defined here.\n",
575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                filename, old->name.lineno);
576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        err = 1;
577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                member = member->next;
580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        items = items->next;
584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiexactly_one_interface(const char* filename, const document_item_type* items, const Options& options,
591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                      bool* onlyParcelable)
592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (items == NULL) {
594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s: file does not contain any interfaces\n",
595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename);
596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const document_item_type* next = items->next;
600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Allow parcelables to skip the "one-only" rule.
601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (items->next != NULL && next->item_type != USER_DATA_TYPE) {
602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int lineno = -1;
603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (next->item_type == INTERFACE_TYPE_BINDER) {
604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            lineno = ((interface_type*)next)->interface_token.lineno;
605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (next->item_type == INTERFACE_TYPE_RPC) {
607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            lineno = ((interface_type*)next)->interface_token.lineno;
608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, lineno);
611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (items->item_type == USER_DATA_TYPE) {
615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *onlyParcelable = true;
616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (options.failOnParcelable) {
617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            " parcelables or flattenables,\n", filename,
619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            ((user_data_type*)items)->keyword_token.lineno);
620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            "may not go in the Makefile.\n", filename,
622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            ((user_data_type*)items)->keyword_token.lineno);
623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 1;
624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *onlyParcelable = false;
627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 0;
630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid
634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_dep_file(const Options& options, const document_item_type* items)
635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /* we open the file in binary mode to ensure that the same output is
637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * generated on all platforms !!
638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILE* to = NULL;
640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (options.autoDepFile) {
641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        string fileName = options.outputFileName + ".d";
642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        to = fopen(fileName.c_str(), "wb");
643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        to = fopen(options.depFileName.c_str(), "wb");
645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (to == NULL) {
648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* slash = "\\";
652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import_info* import = g_imports;
653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (import == NULL) {
654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        slash = "";
655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(to, "%s: \\\n", options.outputFileName.c_str());
659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // parcelable: there's no output file.
661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(to, " : \\\n");
662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(to, "  %s %s\n", options.inputFileName.c_str(), slash);
664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (import->next == NULL) {
667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            slash = "";
668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (import->filename) {
670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(to, "  %s %s\n", import->filename, slash);
671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(to, "\n");
676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Output "<imported_file>: " so make won't fail if the imported file has
678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // been deleted, moved or renamed in incremental build.
679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import = g_imports;
680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (import->filename) {
682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(to, "%s :\n", import->filename);
683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fclose(to);
688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic string
692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_outputFileName2(const Options& options, const buffer_type& name, const char* package)
693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    string result;
695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // create the path to the destination folder based on the
697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // interface package name
698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result = options.outputBaseFolder;
699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result += OS_PATH_SEPARATOR;
700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    string packageStr = package;
702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    size_t len = packageStr.length();
703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i=0; i<len; i++) {
704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (packageStr[i] == '.') {
705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            packageStr[i] = OS_PATH_SEPARATOR;
706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result += packageStr;
710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // add the filename by replacing the .aidl extension to .java
712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* p = strchr(name.data, '.');
713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    len = p ? p-name.data : strlen(name.data);
714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result += OS_PATH_SEPARATOR;
716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result.append(name.data, len);
717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    result += ".java";
718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return result;
720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic string
724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_outputFileName(const Options& options, const document_item_type* items)
725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // items has already been checked to have only one interface.
727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        interface_type* type = (interface_type*)items;
729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return generate_outputFileName2(options, type->name, type->package);
731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (items->item_type == USER_DATA_TYPE) {
732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        user_data_type* type = (user_data_type*)items;
733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return generate_outputFileName2(options, type->name, type->package);
734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // I don't think we can come here, but safer than returning NULL.
737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    string result;
738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return result;
739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void
745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_outputFilePath(const string& path) {
746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    size_t len = path.length();
747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i=0; i<len ; i++) {
748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (path[i] == OS_PATH_SEPARATOR) {
749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            string p = path.substr(0, i);
750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (access(path.data(), F_OK) != 0) {
751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_MS_C_RUNTIME
752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                _mkdir(p.data());
753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mkdir(p.data(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiparse_preprocessed_file(const string& filename)
765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err;
767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILE* f = fopen(filename.c_str(), "rb");
769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (f == NULL) {
770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "aidl: can't open preprocessed file: %s\n",
771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                filename.c_str());
772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int lineno = 1;
776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char line[1024];
777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char type[1024];
778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char fullname[1024];
779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (fgets(line, sizeof(line), f)) {
780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // skip comments and empty lines
781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!line[0] || strncmp(line, "//", 2) == 0) {
782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski          continue;
783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sscanf(line, "%s %[^; \r\n\t];", type, fullname);
786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        char* packagename;
788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        char* classname = rfind(fullname, '.');
789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (classname != NULL) {
790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            *classname = '\0';
791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            classname++;
792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            packagename = fullname;
793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            classname = fullname;
795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            packagename = NULL;
796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno,
799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        //        type, packagename, classname);
800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        document_item_type* doc;
801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (0 == strcmp("parcelable", type)) {
803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* parcl = (user_data_type*)malloc(
804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    sizeof(user_data_type));
805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            memset(parcl, 0, sizeof(user_data_type));
806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->document_item.item_type = USER_DATA_TYPE;
807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->keyword_token.lineno = lineno;
808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->keyword_token.data = strdup(type);
809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->package = packagename ? strdup(packagename) : NULL;
810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->name.lineno = lineno;
811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->name.data = strdup(classname);
812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->semicolon_token.lineno = lineno;
813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->semicolon_token.data = strdup(";");
814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->flattening_methods = PARCELABLE_DATA;
815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            doc = (document_item_type*)parcl;
816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (0 == strcmp("flattenable", type)) {
818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* parcl = (user_data_type*)malloc(
819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    sizeof(user_data_type));
820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            memset(parcl, 0, sizeof(user_data_type));
821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->document_item.item_type = USER_DATA_TYPE;
822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->keyword_token.lineno = lineno;
823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->keyword_token.data = strdup(type);
824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->package = packagename ? strdup(packagename) : NULL;
825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->name.lineno = lineno;
826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->name.data = strdup(classname);
827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->semicolon_token.lineno = lineno;
828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->semicolon_token.data = strdup(";");
829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            parcl->flattening_methods = RPC_DATA;
830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            doc = (document_item_type*)parcl;
831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else if (0 == strcmp("interface", type)) {
833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* iface = (interface_type*)malloc(
834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    sizeof(interface_type));
835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            memset(iface, 0, sizeof(interface_type));
836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->document_item.item_type = INTERFACE_TYPE_BINDER;
837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->interface_token.lineno = lineno;
838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->interface_token.data = strdup(type);
839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->package = packagename ? strdup(packagename) : NULL;
840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->name.lineno = lineno;
841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->name.data = strdup(classname);
842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->open_brace_token.lineno = lineno;
843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->open_brace_token.data = strdup("{");
844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->close_brace_token.lineno = lineno;
845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iface->close_brace_token.data = strdup("}");
846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            doc = (document_item_type*)iface;
847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else {
849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "%s:%d: bad type in line: %s\n",
850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    filename.c_str(), lineno, line);
851b30296b5fda75bf383c7ab3f567eb41820747869Elliott Hughes            fclose(f);
852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 1;
853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = gather_types(filename.c_str(), doc);
855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        lineno++;
856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!feof(f)) {
859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "%s:%d: error reading file, line to long.\n",
860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                filename.c_str(), lineno);
861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fclose(f);
865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 0;
866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicheck_and_assign_method_ids(const char * filename, interface_item_type* first_item)
870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Check whether there are any methods with manually assigned id's and any that are not.
872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Either all method id's must be manually assigned or all of them must not.
873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Also, check for duplicates of user set id's and that the id's are within the proper bounds.
874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    set<int> usedIds;
875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    interface_item_type* item = first_item;
876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool hasUnassignedIds = false;
877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool hasAssignedIds = false;
878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (item != NULL) {
879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (item->item_type == METHOD_TYPE) {
880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            method_type* method_item = (method_type*)item;
881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (method_item->hasId) {
882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                hasAssignedIds = true;
883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                method_item->assigned_id = atoi(method_item->id.data);
884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // Ensure that the user set id is not duplicated.
885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (usedIds.find(method_item->assigned_id) != usedIds.end()) {
886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // We found a duplicate id, so throw an error.
887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    fprintf(stderr,
888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            "%s:%d Found duplicate method id (%d) for method: %s\n",
889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, method_item->id.lineno,
890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            method_item->assigned_id, method_item->name.data);
891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return 1;
892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // Ensure that the user set id is within the appropriate limits
894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (method_item->assigned_id < MIN_USER_SET_METHOD_ID ||
895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        method_item->assigned_id > MAX_USER_SET_METHOD_ID) {
896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            filename, method_item->id.lineno,
898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            method_item->assigned_id, method_item->name.data);
899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            MIN_USER_SET_METHOD_ID, MAX_USER_SET_METHOD_ID);
901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return 1;
902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                usedIds.insert(method_item->assigned_id);
904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } else {
905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                hasUnassignedIds = true;
906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (hasAssignedIds && hasUnassignedIds) {
908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                fprintf(stderr,
909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        "%s: You must either assign id's to all methods or to none of them.\n",
910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        filename);
911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return 1;
912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        item = item->next;
915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // In the case that all methods have unassigned id's, set a unique id for them.
918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (hasUnassignedIds) {
919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int newId = 0;
920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        item = first_item;
921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        while (item != NULL) {
922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (item->item_type == METHOD_TYPE) {
923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                method_type* method_item = (method_type*)item;
924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                method_item->assigned_id = newId++;
925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            item = item->next;
927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // success
931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 0;
932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskicompile_aidl(Options& options)
937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err = 0, N;
939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    set_import_paths(options.importPaths);
941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    register_base_types();
943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // import the preprocessed file
945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    N = options.preprocessedFiles.size();
946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (int i=0; i<N; i++) {
947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const string& s = options.preprocessedFiles[i];
948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err |= parse_preprocessed_file(s);
949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != 0) {
951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // parse the main file
955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    g_callbacks = &g_mainCallbacks;
956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err = parse_aidl(options.inputFileName.c_str());
957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    document_item_type* mainDoc = g_document;
958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    g_document = NULL;
959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // parse the imports
961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    g_callbacks = &g_mainCallbacks;
962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import_info* import = g_imports;
963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (NAMES.Find(import->neededClass) == NULL) {
965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            import->filename = find_import_file(import->neededClass);
966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (!import->filename) {
967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                fprintf(stderr, "%s:%d: couldn't find import for class %s\n",
968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        import->from, import->statement.lineno,
969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        import->neededClass);
970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                err |= 1;
971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } else {
972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                err |= parse_aidl(import->filename);
973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                import->doc = g_document;
974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (import->doc == NULL) {
975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    err |= 1;
976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // bail out now if parsing wasn't successful
982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != 0 || mainDoc == NULL) {
983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        //fprintf(stderr, "aidl: parsing failed, stopping.\n");
984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // complain about ones that aren't in the right files
988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err |= check_filenames(options.inputFileName.c_str(), mainDoc);
989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import = g_imports;
990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err |= check_filenames(import->filename, import->doc);
992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // gather the types that have been declared
996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err |= gather_types(options.inputFileName.c_str(), mainDoc);
997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import = g_imports;
998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err |= gather_types(import->filename, import->doc);
1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0
1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    printf("---- main doc ----\n");
1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    test_document(mainDoc);
1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    import = g_imports;
1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (import) {
1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        printf("---- import doc ----\n");
1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        test_document(import->doc);
1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        import = import->next;
1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    NAMES.Dump();
1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // check the referenced types in mainDoc to make sure we've imported them
1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err |= check_types(options.inputFileName.c_str(), mainDoc);
1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // finally, there really only needs to be one thing in mainDoc, and it
1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // needs to be an interface.
1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool onlyParcelable = false;
1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable);
1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // If this includes an interface definition, then assign method ids and validate.
1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!onlyParcelable) {
1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err |= check_and_assign_method_ids(options.inputFileName.c_str(),
1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ((interface_type*)mainDoc)->interface_items);
1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // after this, there shouldn't be any more errors because of the
1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // input.
1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != 0 || mainDoc == NULL) {
1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // if needed, generate the outputFileName from the outputBaseFolder
1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (options.outputFileName.length() == 0 &&
1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            options.outputBaseFolder.length() > 0) {
1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        options.outputFileName = generate_outputFileName(options, mainDoc);
1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // if we were asked to, generate a make dependency file
1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // unless it's a parcelable *and* it's supposed to fail on parcelable
1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((options.autoDepFile || options.depFileName != "") &&
1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            !(onlyParcelable && options.failOnParcelable)) {
1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // make sure the folders of the output file all exists
1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        check_outputFilePath(options.outputFileName);
1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        generate_dep_file(options, mainDoc);
1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // they didn't ask to fail on parcelables, so just exit quietly.
1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (onlyParcelable && !options.failOnParcelable) {
1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // make sure the folders of the output file all exists
1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    check_outputFilePath(options.outputFileName);
1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    err = generate_java(options.outputFileName, options.inputFileName.c_str(),
1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        (interface_type*)mainDoc);
1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int
1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipreprocess_aidl(const Options& options)
1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    vector<string> lines;
1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int err;
1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // read files
1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int N = options.filesToPreprocess.size();
1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (int i=0; i<N; i++) {
1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        g_callbacks = &g_mainCallbacks;
1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = parse_aidl(options.filesToPreprocess[i].c_str());
1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != 0) {
1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return err;
1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        document_item_type* doc = g_document;
1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        string line;
1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (doc->item_type == USER_DATA_TYPE) {
1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            user_data_type* parcelable = (user_data_type*)doc;
1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line = "parcelable ";
1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if ((parcelable->flattening_methods & RPC_DATA) != 0) {
1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line = "flattenable ";
1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (parcelable->package) {
1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line += parcelable->package;
1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line += '.';
1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            line += parcelable->name.data;
1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            line = "interface ";
1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            interface_type* iface = (interface_type*)doc;
1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (iface->package) {
1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line += iface->package;
1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                line += '.';
1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            line += iface->name.data;
1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        line += ";\n";
1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        lines.push_back(line);
1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // write preprocessed file
1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int fd = open( options.outputFileName.c_str(),
1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                   O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_MS_C_RUNTIME
1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                   _S_IREAD|_S_IWRITE);
1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                   S_IRUSR|S_IWUSR|S_IRGRP);
1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (fd == -1) {
1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "aidl: could not open file for write: %s\n",
1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                options.outputFileName.c_str());
1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    N = lines.size();
1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (int i=0; i<N; i++) {
1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const string& s = lines[i];
1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int len = s.length();
1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (len != write(fd, s.c_str(), len)) {
1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "aidl: error writing to file %s\n",
1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                options.outputFileName.c_str());
1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            close(fd);
1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            unlink(options.outputFileName.c_str());
1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 1;
1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    close(fd);
1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 0;
1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ==========================================================
1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint
1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskimain(int argc, const char **argv)
1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Options options;
1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int result = parse_options(argc, argv, &options);
1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (result) {
1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return result;
1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (options.task)
1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case COMPILE_AIDL:
1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return compile_aidl(options);
1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case PREPROCESS_AIDL:
1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return preprocess_aidl(options);
1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(stderr, "aidl: internal error\n");
1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return 1;
1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1158