• 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 in              { SET_BUFFER(IN); return IN; }
85 out             { SET_BUFFER(OUT); return OUT; }
86 inout           { SET_BUFFER(INOUT); return INOUT; }
87 oneway          { SET_BUFFER(ONEWAY); return ONEWAY; }
88 
89 {brackets}+     { SET_BUFFER(ARRAY); return ARRAY; }
90 
91 {identifier}                                        { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
92 {identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\>    {
93                                                       SET_BUFFER(GENERIC); return GENERIC; }
94 
95     /* syntax error! */
96 .               { printf("UNKNOWN(%s)", yytext);
97                   yylval.buffer.lineno = yylineno;
98                   yylval.buffer.token = IDENTIFIER;
99                   yylval.buffer.data = strdup(yytext);
100                   return IDENTIFIER;
101                 }
102 
103 %%
104 
105 // comment and whitespace handling
106 // ================================================
107 extra_text_type* g_extraText = NULL;
108 extra_text_type* g_nextExtraText = NULL;
109 
begin_extra_text(unsigned lineno,which_extra_text which)110 void begin_extra_text(unsigned lineno, which_extra_text which)
111 {
112     extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
113     text->lineno = lineno;
114     text->which = which;
115     text->data = NULL;
116     text->len = 0;
117     text->next = NULL;
118     if (g_nextExtraText == NULL) {
119         g_extraText = text;
120     } else {
121         g_nextExtraText->next = text;
122     }
123     g_nextExtraText = text;
124 }
125 
append_extra_text(char * text)126 void append_extra_text(char* text)
127 {
128     if (g_nextExtraText->data == NULL) {
129         g_nextExtraText->data = strdup(text);
130         g_nextExtraText->len = strlen(text);
131     } else {
132         char* orig = g_nextExtraText->data;
133         unsigned oldLen = g_nextExtraText->len;
134         unsigned len = strlen(text);
135         g_nextExtraText->len += len;
136         g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
137         memcpy(g_nextExtraText->data, orig, oldLen);
138         memcpy(g_nextExtraText->data+oldLen, text, len);
139         g_nextExtraText->data[g_nextExtraText->len] = '\0';
140         free(orig);
141     }
142 }
143 
144 extra_text_type*
get_extra_text(void)145 get_extra_text(void)
146 {
147     extra_text_type* result = g_extraText;
148     g_extraText = NULL;
149     g_nextExtraText = NULL;
150     return result;
151 }
152 
drop_extra_text(void)153 void drop_extra_text(void)
154 {
155     extra_text_type* p = g_extraText;
156     while (p) {
157         extra_text_type* next = p->next;
158         free(p->data);
159         free(p);
160         free(next);
161     }
162     g_extraText = NULL;
163     g_nextExtraText = NULL;
164 }
165 
166 
167 // package handling
168 // ================================================
do_package_statement(const char * importText)169 void do_package_statement(const char* importText)
170 {
171     if (g_currentPackage) free((void*)g_currentPackage);
172     g_currentPackage = parse_import_statement(importText);
173 }
174 
175 
176 // main parse function
177 // ================================================
178 char const* g_currentFilename = NULL;
179 char const* g_currentPackage = NULL;
180 
181 int yyparse(void);
182 
parse_aidl(char const * filename)183 int parse_aidl(char const *filename)
184 {
185     yyin = fopen(filename, "r");
186     if (yyin) {
187         char const* oldFilename = g_currentFilename;
188         char const* oldPackage = g_currentPackage;
189         g_currentFilename = strdup(filename);
190 
191         g_error = 0;
192         yylineno = 1;
193         int rv = yyparse();
194         if (g_error != 0) {
195             rv = g_error;
196         }
197 
198         free((void*)g_currentFilename);
199         g_currentFilename = oldFilename;
200 
201         if (g_currentPackage) free((void*)g_currentPackage);
202         g_currentPackage = oldPackage;
203 
204         return rv;
205     } else {
206         fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
207         return 1;
208     }
209 }
210 
211