• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 %{
2 #include "aidl_language.h"
3 #include "aidl_language_y.h"
4 #include "search_path.h"
5 #include <string.h>
6 #include <stdlib.h>
7 
8 extern YYSTYPE yylval;
9 
10 // comment and whitespace handling
11 // these functions save a copy of the buffer
12 static void begin_extra_text(unsigned lineno, which_extra_text which);
13 static void append_extra_text(char* text);
14 static extra_text_type* get_extra_text(void);   // you now own the object
15                                                 // this returns
16 static void drop_extra_text(void);
17 
18 // package handling
19 static void do_package_statement(const char* importText);
20 
21 #define SET_BUFFER(t) \
22     do { \
23         yylval.buffer.lineno = yylineno; \
24         yylval.buffer.token = (t); \
25         yylval.buffer.data = strdup(yytext); \
26         yylval.buffer.extra = get_extra_text(); \
27     } while(0)
28 
29 %}
30 
31 %option yylineno
32 %option noyywrap
33 
34 %x COPYING LONG_COMMENT
35 
36 identifier  [_a-zA-Z][_a-zA-Z0-9\.]*
37 whitespace  ([ \t\n\r]+)
38 brackets    \[{whitespace}?\]
39 
40 %%
41 
42 
43 \%\%\{              { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); }
44 <COPYING>\}\%\%     { BEGIN(INITIAL); }
45 <COPYING>.*\n       { append_extra_text(yytext); }
46 <COPYING>.*         { append_extra_text(yytext); }
47 <COPYING>\n+        { append_extra_text(yytext); }
48 
49 
50 \/\*                            { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT);
51                                   BEGIN(LONG_COMMENT); }
52 <LONG_COMMENT>[^*]*             { append_extra_text(yytext); }
53 <LONG_COMMENT>\*+[^/]           { append_extra_text(yytext); }
54 <LONG_COMMENT>\n                { append_extra_text(yytext); }
55 <LONG_COMMENT>\**\/             { BEGIN(INITIAL); }
56 
57 ^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?;  {
58                                                 SET_BUFFER(IMPORT);
59                                                 return IMPORT;
60                                             }
61 ^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?;  {
62                                                 do_package_statement(yytext);
63                                                 SET_BUFFER(PACKAGE);
64                                                 return PACKAGE;
65                                             }
66 <<EOF>>             { yyterminate(); }
67 
68 \/\/.*\n            { begin_extra_text(yylineno, SHORT_COMMENT);
69                         append_extra_text(yytext); }
70 
71 {whitespace}    { /* begin_extra_text(yylineno, WHITESPACE);
72                     append_extra_text(yytext); */ }
73 
74 ;               { SET_BUFFER(';'); return ';'; }
75 \{              { SET_BUFFER('{'); return '{'; }
76 \}              { SET_BUFFER('}'); return '}'; }
77 \(              { SET_BUFFER('('); return '('; }
78 \)              { SET_BUFFER(')'); return ')'; }
79 ,               { SET_BUFFER(','); return ','; }
80 
81     /* keywords */
82 parcelable      { SET_BUFFER(PARCELABLE); return PARCELABLE; }
83 interface       { SET_BUFFER(INTERFACE); return INTERFACE; }
84 flattenable     { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
85 rpc             { SET_BUFFER(INTERFACE); return RPC; }
86 in              { SET_BUFFER(IN); return IN; }
87 out             { SET_BUFFER(OUT); return OUT; }
88 inout           { SET_BUFFER(INOUT); return INOUT; }
89 oneway          { SET_BUFFER(ONEWAY); return ONEWAY; }
90 
91 {brackets}+     { SET_BUFFER(ARRAY); return ARRAY; }
92 
93 {identifier}                                        { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
94 {identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\>    {
95                                                       SET_BUFFER(GENERIC); return GENERIC; }
96 
97     /* syntax error! */
98 .               { printf("UNKNOWN(%s)", yytext);
99                   yylval.buffer.lineno = yylineno;
100                   yylval.buffer.token = IDENTIFIER;
101                   yylval.buffer.data = strdup(yytext);
102                   return IDENTIFIER;
103                 }
104 
105 %%
106 
107 // comment and whitespace handling
108 // ================================================
109 extra_text_type* g_extraText = NULL;
110 extra_text_type* g_nextExtraText = NULL;
111 
begin_extra_text(unsigned lineno,which_extra_text which)112 void begin_extra_text(unsigned lineno, which_extra_text which)
113 {
114     extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
115     text->lineno = lineno;
116     text->which = which;
117     text->data = NULL;
118     text->len = 0;
119     text->next = NULL;
120     if (g_nextExtraText == NULL) {
121         g_extraText = text;
122     } else {
123         g_nextExtraText->next = text;
124     }
125     g_nextExtraText = text;
126 }
127 
append_extra_text(char * text)128 void append_extra_text(char* text)
129 {
130     if (g_nextExtraText->data == NULL) {
131         g_nextExtraText->data = strdup(text);
132         g_nextExtraText->len = strlen(text);
133     } else {
134         char* orig = g_nextExtraText->data;
135         unsigned oldLen = g_nextExtraText->len;
136         unsigned len = strlen(text);
137         g_nextExtraText->len += len;
138         g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
139         memcpy(g_nextExtraText->data, orig, oldLen);
140         memcpy(g_nextExtraText->data+oldLen, text, len);
141         g_nextExtraText->data[g_nextExtraText->len] = '\0';
142         free(orig);
143     }
144 }
145 
146 extra_text_type*
get_extra_text(void)147 get_extra_text(void)
148 {
149     extra_text_type* result = g_extraText;
150     g_extraText = NULL;
151     g_nextExtraText = NULL;
152     return result;
153 }
154 
drop_extra_text(void)155 void drop_extra_text(void)
156 {
157     extra_text_type* p = g_extraText;
158     while (p) {
159         extra_text_type* next = p->next;
160         free(p->data);
161         free(p);
162         free(next);
163     }
164     g_extraText = NULL;
165     g_nextExtraText = NULL;
166 }
167 
168 
169 // package handling
170 // ================================================
do_package_statement(const char * importText)171 void do_package_statement(const char* importText)
172 {
173     if (g_currentPackage) free((void*)g_currentPackage);
174     g_currentPackage = parse_import_statement(importText);
175 }
176 
177 
178 // main parse function
179 // ================================================
180 char const* g_currentFilename = NULL;
181 char const* g_currentPackage = NULL;
182 
183 int yyparse(void);
184 
parse_aidl(char const * filename)185 int parse_aidl(char const *filename)
186 {
187     yyin = fopen(filename, "r");
188     if (yyin) {
189         char const* oldFilename = g_currentFilename;
190         char const* oldPackage = g_currentPackage;
191         g_currentFilename = strdup(filename);
192 
193         g_error = 0;
194         yylineno = 1;
195         int rv = yyparse();
196         if (g_error != 0) {
197             rv = g_error;
198         }
199 
200         free((void*)g_currentFilename);
201         g_currentFilename = oldFilename;
202 
203         if (g_currentPackage) free((void*)g_currentPackage);
204         g_currentPackage = oldPackage;
205 
206         return rv;
207     } else {
208         fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
209         return 1;
210     }
211 }
212 
213