19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "aidl_language.h"
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "options.h"
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "search_path.h"
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Type.h"
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "generate_java.h"
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/param.h>
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <map>
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MS_C_RUNTIME
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <io.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef O_BINARY
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#  define O_BINARY  0
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu// The following are gotten as the offset from the allowable id's between
2702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
2802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
2902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu#define MIN_USER_SET_METHOD_ID                0
3002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu#define MAX_USER_SET_METHOD_ID                16777214
3102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace std;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttest_document(document_item_type* d)
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (d) {
38fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (d->item_type == INTERFACE_TYPE_BINDER) {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* c = (interface_type*)d;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("interface %s %s {\n", c->package, c->name.data);
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_item_type *q = (interface_item_type*)c->interface_items;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (q) {
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (q->item_type == METHOD_TYPE) {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    method_type *m = (method_type*)q;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("  %s %s(", m->type.type.data, m->name.data);
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg_type *p = m->args;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    while (p) {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        printf("%s %s",p->type.type.data,p->name.data);
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (p->next) printf(", ");
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        p=p->next;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf(")");
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf(";\n");
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                q=q->next;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            printf("}\n");
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        else if (d->item_type == USER_DATA_TYPE) {
60a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* b = (user_data_type*)d;
61a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
62a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                printf("parcelable %s %s;\n", b->package, b->name.data);
63a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            }
64a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            if ((b->flattening_methods & RPC_DATA) != 0) {
65a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                printf("flattenable %s %s;\n", b->package, b->name.data);
66a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            }
677db766c3fec2795b08d237f29b972f474983684bJoe Onorato        }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
69066aa99d2d114d46406e00fcc23d193d117395b1Scott Turner            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        d = d->next;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconvert_direction(const char* direction)
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (direction == NULL) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return IN_PARAMETER;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 == strcmp(direction, "in")) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return IN_PARAMETER;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 == strcmp(direction, "out")) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return OUT_PARAMETER;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return INOUT_PARAMETER;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct import_info {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* from;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* filename;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buffer_type statement;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* neededClass;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    document_item_type* doc;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct import_info* next;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdocument_item_type* g_document = NULL;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport_info* g_imports = NULL;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmain_document_parsed(document_item_type* d)
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_document = d;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmain_import_parsed(buffer_type* statement)
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import_info* import = (import_info*)malloc(sizeof(import_info));
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(import, 0, sizeof(import_info));
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->from = strdup(g_currentFilename);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->statement.lineno = statement->lineno;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->statement.data = strdup(statement->data);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->statement.extra = NULL;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->next = g_imports;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import->neededClass = parse_import_statement(statement->data);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_imports = import;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ParserCallbacks g_mainCallbacks = {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    &main_document_parsed,
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    &main_import_parsed
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectchar*
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectparse_import_statement(const char* text)
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* end;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (isspace(*text)) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        text++;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (!isspace(*text)) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        text++;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (isspace(*text)) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        text++;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    end = text;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (!isspace(*end) && *end != ';') {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        end++;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = end-text;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* rv = (char*)malloc(len+1);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(rv, text, len);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rv[len] = '\0';
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return rv;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport_import_parsed(buffer_type* statement)
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic ParserCallbacks g_importCallbacks = {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    &main_document_parsed,
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    &import_import_parsed
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectcheck_filename(const char* filename, const char* package, buffer_type* name)
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* p;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    string expected;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    string fn;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char cwd[MAXPATHLEN];
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool valid = false;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_WINDOWS_PATHS
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isalpha(filename[0]) && filename[1] == ':'
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        && filename[2] == OS_PATH_SEPARATOR) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (filename[0] == OS_PATH_SEPARATOR) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fn = filename;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fn = getcwd(cwd, sizeof(cwd));
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len = fn.length();
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fn[len-1] != OS_PATH_SEPARATOR) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fn += OS_PATH_SEPARATOR;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fn += filename;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (package) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        expected = package;
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        expected += '.';
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = expected.length();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<len; i++) {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (expected[i] == '.') {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            expected[i] = OS_PATH_SEPARATOR;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    p = strchr(name->data, '.');
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = p ? p-name->data : strlen(name->data);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    expected.append(name->data, len);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    expected += ".aidl";
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = fn.length();
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    valid = (len >= expected.length());
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (valid) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p = fn.c_str() + (len - expected.length());
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_WINDOWS_PATHS
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (OS_PATH_SEPARATOR != '/') {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Input filename under cygwin most likely has / separators
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // whereas the expected string uses \\ separators. Adjust
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // them accordingly.
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          for (char *c = const_cast<char *>(p); *c; ++c) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (*c == '/') *c = OS_PATH_SEPARATOR;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef OS_CASE_SENSITIVE
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        valid = (expected == p);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        valid = !strcasecmp(expected.c_str(), p);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!valid) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d interface %s should be declared in a file"
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " called %s.\n",
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filename, name->lineno, name->data, expected.c_str());
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectcheck_filenames(const char* filename, document_item_type* items)
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err = 0;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (items) {
252a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        if (items->item_type == USER_DATA_TYPE) {
253a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* p = (user_data_type*)items;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err |= check_filename(filename, p->package, &p->name);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
256fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        else if (items->item_type == INTERFACE_TYPE_BINDER
257fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                || items->item_type == INTERFACE_TYPE_RPC) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* c = (interface_type*)items;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err |= check_filename(filename, c->package, &c->name);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "aidl: internal error unkown document type %d.\n",
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        items->item_type);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        items = items->next;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char*
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectkind_to_string(int kind)
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (kind)
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case Type::INTERFACE:
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "an interface";
279a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        case Type::USERDATA:
280a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            return "a user data";
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "ERROR";
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char*
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectrfind(char* str, char c)
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* p = str + strlen(str) - 1;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (p >= str) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (*p == c) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return p;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p--;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectgather_types(const char* filename, document_item_type* items)
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err = 0;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (items) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Type* type;
305a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        if (items->item_type == USER_DATA_TYPE) {
306a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* p = (user_data_type*)items;
307a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            type = new UserDataType(p->package ? p->package : "", p->name.data,
308a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                    false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
309a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                    ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
3107db766c3fec2795b08d237f29b972f474983684bJoe Onorato        }
311fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        else if (items->item_type == INTERFACE_TYPE_BINDER
312fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                || items->item_type == INTERFACE_TYPE_RPC) {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* c = (interface_type*)items;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            type = new InterfaceType(c->package ? c->package : "",
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            c->name.data, false, c->oneway,
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            filename, c->name.lineno);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "aidl: internal error %s:%d\n", __FILE__, __LINE__);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Type* old = NAMES.Find(type->QualifiedName());
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (old == NULL) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NAMES.Add(type);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
327fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            if (items->item_type == INTERFACE_TYPE_BINDER) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // for interfaces, also add the stub and proxy types, we don't
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // bother checking these for duplicates, because the parser
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // won't let us do it.
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                interface_type* c = (interface_type*)items;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                string name = c->name.data;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name += ".Stub";
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Type* stub = new Type(c->package ? c->package : "",
3367db766c3fec2795b08d237f29b972f474983684bJoe Onorato                                        name, Type::GENERATED, false, false, false,
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        filename, c->name.lineno);
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NAMES.Add(stub);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = c->name.data;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name += ".Stub.Proxy";
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Type* proxy = new Type(c->package ? c->package : "",
3437db766c3fec2795b08d237f29b972f474983684bJoe Onorato                                        name, Type::GENERATED, false, false, false,
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        filename, c->name.lineno);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NAMES.Add(proxy);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
347fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            else if (items->item_type == INTERFACE_TYPE_RPC) {
348fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                // for interfaces, also add the service base type, we don't
349fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                // bother checking these for duplicates, because the parser
350fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                // won't let us do it.
351fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                interface_type* c = (interface_type*)items;
352fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
353fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                string name = c->name.data;
354fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                name += ".ServiceBase";
355fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                Type* base = new Type(c->package ? c->package : "",
3567db766c3fec2795b08d237f29b972f474983684bJoe Onorato                                        name, Type::GENERATED, false, false, false,
357fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                        filename, c->name.lineno);
358fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                NAMES.Add(base);
359fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (old->Kind() == Type::BUILT_IN) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "%s:%d attempt to redefine built in class %s\n",
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            filename, type->DeclLine(),
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            type->QualifiedName().c_str());
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = 1;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else if (type->Kind() != old->Kind()) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const char* oldKind = kind_to_string(old->Kind());
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const char* newKind = kind_to_string(type->Kind());
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "%s:%d attempt to redefine %s as %s,\n",
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            filename, type->DeclLine(),
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            type->QualifiedName().c_str(), newKind);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "%s:%d    previously defined here as %s.\n",
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            old->DeclFile().c_str(), old->DeclLine(), oldKind);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = 1;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        items = items->next;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmatches_keyword(const char* str)
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static const char* KEYWORDS[] = { "abstract", "assert", "boolean", "break",
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "byte", "case", "catch", "char", "class", "const", "continue",
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "default", "do", "double", "else", "enum", "extends", "final",
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "finally", "float", "for", "goto", "if", "implements", "import",
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "instanceof", "int", "interface", "long", "native", "new", "package",
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "private", "protected", "public", "return", "short", "static",
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "strictfp", "super", "switch", "synchronized", "this", "throw",
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "throws", "transient", "try", "void", "volatile", "while",
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "true", "false", "null",
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NULL
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char** k = KEYWORDS;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (*k) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == strcmp(str, *k)) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        k++;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
4117db766c3fec2795b08d237f29b972f474983684bJoe Onoratocheck_method(const char* filename, int kind, method_type* m)
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err = 0;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // return type
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Type* returnType = NAMES.Search(m->type.type.data);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (returnType == NULL) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d unknown return type %s\n", filename,
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    m->type.type.lineno, m->type.type.data);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = 1;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
424e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato    if (returnType == EVENT_FAKE_TYPE) {
425e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        if (kind != INTERFACE_TYPE_RPC) {
426e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            fprintf(stderr, "%s:%d event methods only supported for rpc interfaces\n",
427e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                    filename, m->type.type.lineno);
428e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            err = 1;
429e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        }
430e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato    } else {
431e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
432e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                    : returnType->CanWriteToRpcData())) {
433e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
434e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                        m->type.type.lineno, m->type.type.data);
435e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            err = 1;
436e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (m->type.dimension > 0 && !returnType->CanBeArray()) {
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d return type %s%s can't be an array.\n", filename,
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                m->type.array_token.lineno, m->type.type.data,
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                m->type.array_token.data);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = 1;
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (m->type.dimension > 1) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d return type %s%s only one"
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " dimensional arrays are supported\n", filename,
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                m->type.array_token.lineno, m->type.type.data,
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                m->type.array_token.data);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = 1;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int index = 1;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    arg_type* arg = m->args;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (arg) {
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Type* t = NAMES.Search(arg->type.type.data);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // check the arg type
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t == NULL) {
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %s (%d) unknown type %s\n",
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    filename, m->type.type.lineno, arg->name.data, index,
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg->type.type.data);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto next;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
468e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato
469e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        if (t == EVENT_FAKE_TYPE) {
470e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            fprintf(stderr, "%s:%d parameter %s (%d) event can not be used as a parameter %s\n",
471e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                    filename, m->type.type.lineno, arg->name.data, index,
472e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                    arg->type.type.data);
473e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            err = 1;
474e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato            goto next;
475e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato        }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4777db766c3fec2795b08d237f29b972f474983684bJoe Onorato        if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        filename, m->type.type.lineno, index,
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        arg->type.type.data, arg->name.data);
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
484fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato        if (returnType == EVENT_FAKE_TYPE
485fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato                && convert_direction(arg->direction.data) != IN_PARAMETER) {
486fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato            fprintf(stderr, "%s:%d parameter %d: '%s %s' All paremeters on events must be 'in'.\n",
487fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato                    filename, m->type.type.lineno, index,
488fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato                    arg->type.type.data, arg->name.data);
489fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato            err = 1;
490fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato            goto next;
491fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato        }
492fcb310f93680b87943c90a321e2beedcb8c528b8Joe Onorato
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (arg->direction.data == NULL
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (arg->type.dimension != 0 || t->CanBeOutParameter())) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out"
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                " parameter, so you must declare it as in,"
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                " out or inout.\n",
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        filename, m->type.type.lineno, index,
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        arg->type.type.data, arg->name.data);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (convert_direction(arg->direction.data) != IN_PARAMETER
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !t->CanBeOutParameter()
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && arg->type.dimension == 0) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d: '%s %s %s' can only be an in"
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " parameter.\n",
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        filename, m->type.type.lineno, index,
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        arg->direction.data, arg->type.type.data,
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        arg->name.data);
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (arg->type.dimension > 0 && !t->CanBeArray()) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' can't be an"
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " array.\n", filename,
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    m->type.array_token.lineno, index, arg->direction.data,
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg->type.type.data, arg->type.array_token.data,
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg->name.data);
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (arg->type.dimension > 1) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d: '%s %s%s %s' only one"
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " dimensional arrays are supported\n", filename,
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    m->type.array_token.lineno, index, arg->direction.data,
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg->type.type.data, arg->type.array_token.data,
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    arg->name.data);
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // check that the name doesn't match a keyword
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (matches_keyword(arg->name.data)) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d parameter %d %s is named the same as a"
535e24dbeafe64278408b3342fcb77756bc7d091791Joe Onorato                    " Java or aidl keyword\n",
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    filename, m->name.lineno, index, arg->name.data);
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = 1;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnext:
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        index++;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        arg = arg->next;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectcheck_types(const char* filename, document_item_type* items)
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err = 0;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (items) {
553a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        // (nothing to check for USER_DATA_TYPE)
5547db766c3fec2795b08d237f29b972f474983684bJoe Onorato        if (items->item_type == INTERFACE_TYPE_BINDER
5557db766c3fec2795b08d237f29b972f474983684bJoe Onorato                || items->item_type == INTERFACE_TYPE_RPC) {
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map<string,method_type*> methodNames;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* c = (interface_type*)items;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_item_type* member = c->interface_items;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (member) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (member->item_type == METHOD_TYPE) {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    method_type* m = (method_type*)member;
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5647db766c3fec2795b08d237f29b972f474983684bJoe Onorato                    err |= check_method(filename, items->item_type, m);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // prevent duplicate methods
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (methodNames.find(m->name.data) == methodNames.end()) {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        methodNames[m->name.data] = m;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr,"%s:%d attempt to redefine method %s,\n",
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                filename, m->name.lineno, m->name.data);
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        method_type* old = methodNames[m->name.data];
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(stderr, "%s:%d    previously defined here.\n",
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                filename, old->name.lineno);
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = 1;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                member = member->next;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        items = items->next;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectexactly_one_interface(const char* filename, const document_item_type* items, const Options& options,
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      bool* onlyParcelable)
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (items == NULL) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s: file does not contain any interfaces\n",
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            filename);
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const document_item_type* next = items->next;
59950a94b86307793ca9d4d8f8564e5f2ba78fdde14Adam Powell    // Allow parcelables to skip the "one-only" rule.
60050a94b86307793ca9d4d8f8564e5f2ba78fdde14Adam Powell    if (items->next != NULL && next->item_type != USER_DATA_TYPE) {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lineno = -1;
602fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (next->item_type == INTERFACE_TYPE_BINDER) {
603fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            lineno = ((interface_type*)next)->interface_token.lineno;
604fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
605fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        else if (next->item_type == INTERFACE_TYPE_RPC) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lineno = ((interface_type*)next)->interface_token.lineno;
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            filename, lineno);
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
613a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato    if (items->item_type == USER_DATA_TYPE) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *onlyParcelable = true;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (options.failOnParcelable) {
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
6177db766c3fec2795b08d237f29b972f474983684bJoe Onorato                            " parcelables or flattenables,\n", filename,
618a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                            ((user_data_type*)items)->keyword_token.lineno);
6197db766c3fec2795b08d237f29b972f474983684bJoe Onorato            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
6207db766c3fec2795b08d237f29b972f474983684bJoe Onorato                            "may not go in the Makefile.\n", filename,
621a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                            ((user_data_type*)items)->keyword_token.lineno);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *onlyParcelable = false;
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
63318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetgenerate_dep_file(const Options& options, const document_item_type* items)
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
63518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    /* we open the file in binary mode to ensure that the same output is
63618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet     * generated on all platforms !!
63718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet     */
63818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    FILE* to = NULL;
63918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    if (options.autoDepFile) {
64018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        string fileName = options.outputFileName + ".d";
64118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        to = fopen(fileName.c_str(), "wb");
64218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    } else {
64318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        to = fopen(options.depFileName.c_str(), "wb");
64418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    }
64518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (to == NULL) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* slash = "\\";
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import_info* import = g_imports;
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (import == NULL) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        slash = "";
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
656fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
65718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        fprintf(to, "%s: \\\n", options.outputFileName.c_str());
65818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    } else {
65918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        // parcelable: there's no output file.
66018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        fprintf(to, " : \\\n");
66118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    }
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(to, "  %s %s\n", options.inputFileName.c_str(), slash);
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (import) {
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (import->next == NULL) {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            slash = "";
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (import->filename) {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(to, "  %s %s\n", import->filename, slash);
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        import = import->next;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(to, "\n");
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6760f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang    // Output "<imported_file>: " so make won't fail if the imported file has
6770f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang    // been deleted, moved or renamed in incremental build.
6780f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang    import = g_imports;
6790f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang    while (import) {
6800f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang        if (import->filename) {
6810f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang            fprintf(to, "%s :\n", import->filename);
6820f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang        }
6830f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang        import = import->next;
6840f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang    }
6850f91c6360266be07bd0e32f7eca151fa1bca26c1Ying Wang
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fclose(to);
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
690ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectstatic string
69118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetgenerate_outputFileName2(const Options& options, const buffer_type& name, const char* package)
692ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project{
693ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    string result;
694ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
69518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // create the path to the destination folder based on the
69618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // interface package name
69718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result = options.outputBaseFolder;
69818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result += OS_PATH_SEPARATOR;
699ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
70018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    string packageStr = package;
70118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    size_t len = packageStr.length();
70218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    for (size_t i=0; i<len; i++) {
70318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        if (packageStr[i] == '.') {
70418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet            packageStr[i] = OS_PATH_SEPARATOR;
705ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
70618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    }
707ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
70818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result += packageStr;
70918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
71018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // add the filename by replacing the .aidl extension to .java
71118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    const char* p = strchr(name.data, '.');
71218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    len = p ? p-name.data : strlen(name.data);
71318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
71418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result += OS_PATH_SEPARATOR;
71518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result.append(name.data, len);
71618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    result += ".java";
717ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
71818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    return result;
71918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet}
72018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
72118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet// ==========================================================
72218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetstatic string
72318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetgenerate_outputFileName(const Options& options, const document_item_type* items)
72418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet{
72518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // items has already been checked to have only one interface.
726fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
72718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        interface_type* type = (interface_type*)items;
72818fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
72918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        return generate_outputFileName2(options, type->name, type->package);
730a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato    } else if (items->item_type == USER_DATA_TYPE) {
731a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        user_data_type* type = (user_data_type*)items;
73218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        return generate_outputFileName2(options, type->name, type->package);
733ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
734ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
73518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // I don't think we can come here, but safer than returning NULL.
73618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    string result;
737ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    return result;
738ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project}
739ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
74018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
74118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
742ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project// ==========================================================
743ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Projectstatic void
74418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetcheck_outputFilePath(const string& path) {
745ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    size_t len = path.length();
746ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    for (size_t i=0; i<len ; i++) {
747ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        if (path[i] == OS_PATH_SEPARATOR) {
748ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            string p = path.substr(0, i);
749ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            if (access(path.data(), F_OK) != 0) {
750ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project#ifdef HAVE_MS_C_RUNTIME
751ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                _mkdir(p.data());
752ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project#else
753ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                mkdir(p.data(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
754ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project#endif
755ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            }
756ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
757ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
758ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project}
759ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
760ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
761ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project// ==========================================================
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectparse_preprocessed_file(const string& filename)
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FILE* f = fopen(filename.c_str(), "rb");
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (f == NULL) {
7694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        fprintf(stderr, "aidl: can't open preprocessed file: %s\n",
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filename.c_str());
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int lineno = 1;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char line[1024];
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char type[1024];
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char fullname[1024];
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (fgets(line, sizeof(line), f)) {
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // skip comments and empty lines
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!line[0] || strncmp(line, "//", 2) == 0) {
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          continue;
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sscanf(line, "%s %[^; \r\n\t];", type, fullname);
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* packagename;
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* classname = rfind(fullname, '.');
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (classname != NULL) {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *classname = '\0';
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            classname++;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            packagename = fullname;
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            classname = fullname;
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            packagename = NULL;
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno,
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //        type, packagename, classname);
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        document_item_type* doc;
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == strcmp("parcelable", type)) {
802a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* parcl = (user_data_type*)malloc(
803a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                    sizeof(user_data_type));
804a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            memset(parcl, 0, sizeof(user_data_type));
805a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->document_item.item_type = USER_DATA_TYPE;
806a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->keyword_token.lineno = lineno;
807a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->keyword_token.data = strdup(type);
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcl->package = packagename ? strdup(packagename) : NULL;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcl->name.lineno = lineno;
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcl->name.data = strdup(classname);
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcl->semicolon_token.lineno = lineno;
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcl->semicolon_token.data = strdup(";");
813a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->flattening_methods = PARCELABLE_DATA;
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doc = (document_item_type*)parcl;
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8167db766c3fec2795b08d237f29b972f474983684bJoe Onorato        else if (0 == strcmp("flattenable", type)) {
817a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* parcl = (user_data_type*)malloc(
818a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                    sizeof(user_data_type));
819a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            memset(parcl, 0, sizeof(user_data_type));
820a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->document_item.item_type = USER_DATA_TYPE;
821a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->keyword_token.lineno = lineno;
822a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->keyword_token.data = strdup(type);
8237db766c3fec2795b08d237f29b972f474983684bJoe Onorato            parcl->package = packagename ? strdup(packagename) : NULL;
8247db766c3fec2795b08d237f29b972f474983684bJoe Onorato            parcl->name.lineno = lineno;
8257db766c3fec2795b08d237f29b972f474983684bJoe Onorato            parcl->name.data = strdup(classname);
8267db766c3fec2795b08d237f29b972f474983684bJoe Onorato            parcl->semicolon_token.lineno = lineno;
8277db766c3fec2795b08d237f29b972f474983684bJoe Onorato            parcl->semicolon_token.data = strdup(";");
828a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            parcl->flattening_methods = RPC_DATA;
8297db766c3fec2795b08d237f29b972f474983684bJoe Onorato            doc = (document_item_type*)parcl;
8307db766c3fec2795b08d237f29b972f474983684bJoe Onorato        }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (0 == strcmp("interface", type)) {
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* iface = (interface_type*)malloc(
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sizeof(interface_type));
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(iface, 0, sizeof(interface_type));
835fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            iface->document_item.item_type = INTERFACE_TYPE_BINDER;
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->interface_token.lineno = lineno;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->interface_token.data = strdup(type);
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->package = packagename ? strdup(packagename) : NULL;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->name.lineno = lineno;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->name.data = strdup(classname);
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->open_brace_token.lineno = lineno;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->open_brace_token.data = strdup("{");
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->close_brace_token.lineno = lineno;
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iface->close_brace_token.data = strdup("}");
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doc = (document_item_type*)iface;
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else {
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "%s:%d: bad type in line: %s\n",
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    filename.c_str(), lineno, line);
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = gather_types(filename.c_str(), doc);
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lineno++;
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!feof(f)) {
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "%s:%d: error reading file, line to long.\n",
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filename.c_str(), lineno);
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fclose(f);
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
86602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chustatic int
86702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chucheck_and_assign_method_ids(const char * filename, interface_item_type* first_item)
86802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu{
86902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // Check whether there are any methods with manually assigned id's and any that are not.
87002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // Either all method id's must be manually assigned or all of them must not.
87102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // Also, check for duplicates of user set id's and that the id's are within the proper bounds.
87202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    set<int> usedIds;
87302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    interface_item_type* item = first_item;
87402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    bool hasUnassignedIds = false;
87502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    bool hasAssignedIds = false;
87602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    while (item != NULL) {
87702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        if (item->item_type == METHOD_TYPE) {
87802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            method_type* method_item = (method_type*)item;
87902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            if (method_item->hasId) {
88002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                hasAssignedIds = true;
88102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                method_item->assigned_id = atoi(method_item->id.data);
88202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                // Ensure that the user set id is not duplicated.
88302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                if (usedIds.find(method_item->assigned_id) != usedIds.end()) {
88402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    // We found a duplicate id, so throw an error.
88502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    fprintf(stderr,
88602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            "%s:%d Found duplicate method id (%d) for method: %s\n",
88702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            filename, method_item->id.lineno,
88802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            method_item->assigned_id, method_item->name.data);
88902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    return 1;
89002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                }
89102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                // Ensure that the user set id is within the appropriate limits
89202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                if (method_item->assigned_id < MIN_USER_SET_METHOD_ID ||
89302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                        method_item->assigned_id > MAX_USER_SET_METHOD_ID) {
89402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
89502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            filename, method_item->id.lineno,
89602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            method_item->assigned_id, method_item->name.data);
89702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
89802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                            MIN_USER_SET_METHOD_ID, MAX_USER_SET_METHOD_ID);
89902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                    return 1;
90002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                }
90102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                usedIds.insert(method_item->assigned_id);
90202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            } else {
90302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                hasUnassignedIds = true;
90402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            }
90502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            if (hasAssignedIds && hasUnassignedIds) {
90602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                fprintf(stderr,
90702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                        "%s: You must either assign id's to all methods or to none of them.\n",
90802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                        filename);
90902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                return 1;
91002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            }
91102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        }
91202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        item = item->next;
91302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    }
91402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu
91502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // In the case that all methods have unassigned id's, set a unique id for them.
91602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    if (hasUnassignedIds) {
91702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        int newId = 0;
91802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        item = first_item;
91902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        while (item != NULL) {
92002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            if (item->item_type == METHOD_TYPE) {
92102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                method_type* method_item = (method_type*)item;
92202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                method_item->assigned_id = newId++;
92302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            }
92402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu            item = item->next;
92502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        }
92602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    }
92702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu
92802822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // success
92902822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    return 0;
93002822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu}
93102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
93418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohetcompile_aidl(Options& options)
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err = 0, N;
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    set_import_paths(options.importPaths);
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    register_base_types();
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // import the preprocessed file
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    N = options.preprocessedFiles.size();
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i=0; i<N; i++) {
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const string& s = options.preprocessedFiles[i];
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err |= parse_preprocessed_file(s);
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0) {
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // parse the main file
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_callbacks = &g_mainCallbacks;
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parse_aidl(options.inputFileName.c_str());
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    document_item_type* mainDoc = g_document;
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_document = NULL;
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // parse the imports
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_callbacks = &g_mainCallbacks;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import_info* import = g_imports;
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (import) {
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NAMES.Find(import->neededClass) == NULL) {
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            import->filename = find_import_file(import->neededClass);
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!import->filename) {
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "%s:%d: couldn't find import for class %s\n",
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        import->from, import->statement.lineno,
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        import->neededClass);
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err |= 1;
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err |= parse_aidl(import->filename);
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                import->doc = g_document;
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (import->doc == NULL) {
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err |= 1;
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        import = import->next;
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // bail out now if parsing wasn't successful
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0 || mainDoc == NULL) {
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //fprintf(stderr, "aidl: parsing failed, stopping.\n");
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // complain about ones that aren't in the right files
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err |= check_filenames(options.inputFileName.c_str(), mainDoc);
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import = g_imports;
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (import) {
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err |= check_filenames(import->filename, import->doc);
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        import = import->next;
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // gather the types that have been declared
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err |= gather_types(options.inputFileName.c_str(), mainDoc);
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import = g_imports;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (import) {
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err |= gather_types(import->filename, import->doc);
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        import = import->next;
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    printf("---- main doc ----\n");
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    test_document(mainDoc);
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    import = g_imports;
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (import) {
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("---- import doc ----\n");
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        test_document(import->doc);
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        import = import->next;
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NAMES.Dump();
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // check the referenced types in mainDoc to make sure we've imported them
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err |= check_types(options.inputFileName.c_str(), mainDoc);
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // finally, there really only needs to be one thing in mainDoc, and it
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // needs to be an interface.
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool onlyParcelable = false;
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable);
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
102202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    // If this includes an interface definition, then assign method ids and validate.
102302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    if (!onlyParcelable) {
102402822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu        err |= check_and_assign_method_ids(options.inputFileName.c_str(),
102502822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu                ((interface_type*)mainDoc)->interface_items);
102602822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu    }
102702822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // after this, there shouldn't be any more errors because of the
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // input.
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != 0 || mainDoc == NULL) {
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
103418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // if needed, generate the outputFileName from the outputBaseFolder
103518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    if (options.outputFileName.length() == 0 &&
103618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet            options.outputBaseFolder.length() > 0) {
103718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        options.outputFileName = generate_outputFileName(options, mainDoc);
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // if we were asked to, generate a make dependency file
104118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // unless it's a parcelable *and* it's supposed to fail on parcelable
104218fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    if ((options.autoDepFile || options.depFileName != "") &&
104318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet            !(onlyParcelable && options.failOnParcelable)) {
104418fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        // make sure the folders of the output file all exists
104518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        check_outputFilePath(options.outputFileName);
104618fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        generate_dep_file(options, mainDoc);
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104918fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    // they didn't ask to fail on parcelables, so just exit quietly.
105018fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    if (onlyParcelable && !options.failOnParcelable) {
105118fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet        return 0;
1052ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
105318fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet
1054ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    // make sure the folders of the output file all exists
105518fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    check_outputFilePath(options.outputFileName);
1056ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
105718fff11e15dc1b4fe53cb37fa39637aa3fb9bc36Xavier Ducrohet    err = generate_java(options.outputFileName, options.inputFileName.c_str(),
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (interface_type*)mainDoc);
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpreprocess_aidl(const Options& options)
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    vector<string> lines;
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int err;
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // read files
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int N = options.filesToPreprocess.size();
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i=0; i<N; i++) {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        g_callbacks = &g_mainCallbacks;
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = parse_aidl(options.filesToPreprocess[i].c_str());
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != 0) {
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        document_item_type* doc = g_document;
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        string line;
1079a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato        if (doc->item_type == USER_DATA_TYPE) {
1080a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            user_data_type* parcelable = (user_data_type*)doc;
1081a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
1082a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                line = "parcelable ";
1083a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            }
1084a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato            if ((parcelable->flattening_methods & RPC_DATA) != 0) {
1085a1c6d909c22e196ef62ddb065fc7821deda8a602Joe Onorato                line = "flattenable ";
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10877db766c3fec2795b08d237f29b972f474983684bJoe Onorato            if (parcelable->package) {
10887db766c3fec2795b08d237f29b972f474983684bJoe Onorato                line += parcelable->package;
10897db766c3fec2795b08d237f29b972f474983684bJoe Onorato                line += '.';
10907db766c3fec2795b08d237f29b972f474983684bJoe Onorato            }
10917db766c3fec2795b08d237f29b972f474983684bJoe Onorato            line += parcelable->name.data;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            line = "interface ";
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            interface_type* iface = (interface_type*)doc;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (iface->package) {
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                line += iface->package;
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                line += '.';
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            line += iface->name.data;
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        line += ";\n";
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lines.push_back(line);
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // write preprocessed file
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd = open( options.outputFileName.c_str(),
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MS_C_RUNTIME
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   _S_IREAD|_S_IWRITE);
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   S_IRUSR|S_IWUSR|S_IRGRP);
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd == -1) {
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "aidl: could not open file for write: %s\n",
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                options.outputFileName.c_str());
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    N = lines.size();
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i=0; i<N; i++) {
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const string& s = lines[i];
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int len = s.length();
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len != write(fd, s.c_str(), len)) {
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "aidl: error writing to file %s\n",
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                options.outputFileName.c_str());
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close(fd);
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unlink(options.outputFileName.c_str());
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(fd);
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ==========================================================
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmain(int argc, const char **argv)
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Options options;
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = parse_options(argc, argv, &options);
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result) {
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (options.task)
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case COMPILE_AIDL:
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return compile_aidl(options);
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case PREPROCESS_AIDL:
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return preprocess_aidl(options);
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "aidl: internal error\n");
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 1;
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1156