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 8extern YYSTYPE yylval; 9 10// comment and whitespace handling 11// these functions save a copy of the buffer 12static void begin_extra_text(unsigned lineno, which_extra_text which); 13static void append_extra_text(char* text); 14static extra_text_type* get_extra_text(void); // you now own the object 15 // this returns 16static void drop_extra_text(void); 17 18// package handling 19static 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 36identifier [_a-zA-Z][_a-zA-Z0-9\.]* 37whitespace ([ \t\n\r]+) 38brackets \[{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 */ 82parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; } 83interface { SET_BUFFER(INTERFACE); return INTERFACE; } 84flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; } 85rpc { SET_BUFFER(INTERFACE); return RPC; } 86in { SET_BUFFER(IN); return IN; } 87out { SET_BUFFER(OUT); return OUT; } 88inout { SET_BUFFER(INOUT); return INOUT; } 89oneway { 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// ================================================ 109extra_text_type* g_extraText = NULL; 110extra_text_type* g_nextExtraText = NULL; 111 112void 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 128void 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 146extra_text_type* 147get_extra_text(void) 148{ 149 extra_text_type* result = g_extraText; 150 g_extraText = NULL; 151 g_nextExtraText = NULL; 152 return result; 153} 154 155void 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// ================================================ 171void 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// ================================================ 180char const* g_currentFilename = NULL; 181char const* g_currentPackage = NULL; 182 183int yyparse(void); 184 185int 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