blob: d89e479160a1d4eeec81ef2454b9d504e993657c [file] [log] [blame]
Alexandre Julliard7d4ee772002-07-16 03:20:45 +00001/*
2 * IDL Compiler
3 *
4 * Copyright 2002 Ove Kaaven
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21%option stack
22%option never-interactive
23
24nl \r?\n
25ws [ \f\t\r]
26cident [a-zA-Z_][0-9a-zA-Z_]*
27int [0-9]+
28hexd [0-9a-fA-F]
29hex 0x{hexd}+
30uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
31
32%x QUOTE
33
34%{
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <ctype.h>
40#include <assert.h>
Gerald Pfeifer2cbbcc12002-07-25 23:57:54 +000041#include <unistd.h>
Alexandre Julliard7d4ee772002-07-16 03:20:45 +000042
43#include "widl.h"
44#include "utils.h"
45#include "parser.h"
Alexandre Julliard5f1565e2002-07-20 19:00:52 +000046#include "../wpp/wpp.h"
Alexandre Julliard7d4ee772002-07-16 03:20:45 +000047
48#include "y.tab.h"
49
50#define YY_USE_PROTOS
51#define YY_NO_UNPUT
52#define YY_NO_TOP_STATE
53
54extern char *temp_name;
55
56static void addcchar(char c);
57static char *get_buffered_cstring(void);
58
59static char *cbuffer;
60static int cbufidx;
61static int cbufalloc = 0;
62
63static int kw_token(const char *kw);
64
65#define MAX_IMPORT_DEPTH 10
66struct {
67 YY_BUFFER_STATE state;
68 char *temp_name;
69} import_stack[MAX_IMPORT_DEPTH];
70int import_stack_ptr = 0;
71
72static void pop_import(void);
73
74%}
75
76/*
77 **************************************************************************
78 * The flexer starts here
79 **************************************************************************
80 */
81%%
82^#.*
83\" yy_push_state(QUOTE); cbufidx = 0;
84<QUOTE>\" {
85 yy_pop_state();
86 yylval.str = get_buffered_cstring();
87 return aSTRING;
88 }
89<QUOTE>\\\\ |
90<QUOTE>\\\" addcchar(yytext[1]);
91<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
92<QUOTE>. addcchar(yytext[0]);
93{uuid} return aUUID;
94{hex} return aNUM;
95{int} return aNUM;
96{cident} return kw_token(yytext);
97\n
98{ws}
99\<\< return SHL;
100\>\> return SHR;
101. return yytext[0];
102<<EOF>> {
103 if (import_stack_ptr) pop_import();
104 else yyterminate();
105 }
106%%
107
108#ifndef yywrap
109int yywrap(void)
110{
111 return 1;
112}
113#endif
114
115static struct {
116 const char *kw;
117 int token;
118 int val;
119} keywords[] = {
120 {"__cdecl", tCDECL},
121 {"__int64", tINT64},
122 {"__stdcall", tSTDCALL},
123 {"_stdcall", tSTDCALL},
124 {"aggregatable", tAGGREGATABLE},
125 {"allocate", tALLOCATE},
126 {"appobject", tAPPOBJECT},
127 {"arrays", tARRAYS},
128 {"async", tASYNC},
129 {"async_uuid", tASYNCUUID},
130 {"auto_handle", tAUTOHANDLE},
131 {"bindable", tBINDABLE},
132 {"boolean", tBOOLEAN},
133 {"broadcast", tBROADCAST},
134 {"byte", tBYTE},
135 {"byte_count", tBYTECOUNT},
136 {"call_as", tCALLAS},
137 {"callback", tCALLBACK},
138 {"case", tCASE},
139 {"char", tCHAR},
140 {"coclass", tCOCLASS},
141 {"code", tCODE},
142 {"comm_status", tCOMMSTATUS},
143 {"const", tCONST},
144 {"context_handle", tCONTEXTHANDLE},
145 {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
146 {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
147 {"control", tCONTROL},
148 {"cpp_quote", tCPPQUOTE},
149/* ... */
150 {"default", tDEFAULT},
151/* ... */
152 {"double", tDOUBLE},
153/* ... */
154 {"enum", tENUM},
155/* ... */
156 {"extern", tEXTERN},
157/* ... */
158 {"float", tFLOAT},
159/* ... */
160 {"hyper", tHYPER},
161/* ... */
162 {"iid_is", tIIDIS},
163/* ... */
164 {"import", tIMPORT},
165 {"importlib", tIMPORTLIB},
166 {"in", tIN},
167 {"include", tINCLUDE},
168 {"in_line", tINLINE},
169 {"int", tINT},
170/* ... */
171 {"interface", tINTERFACE},
172/* ... */
173 {"length_is", tLENGTHIS},
174/* ... */
175 {"local", tLOCAL},
176 {"long", tLONG},
177/* ... */
178 {"object", tOBJECT},
179 {"odl", tODL},
180 {"oleautomation", tOLEAUTOMATION},
181/* ... */
182 {"out", tOUT},
183/* ... */
184 {"pointer_default", tPOINTERDEFAULT},
185/* ... */
186 {"ref", tREF},
187/* ... */
188 {"short", tSHORT},
189 {"signed", tSIGNED},
190 {"size_is", tSIZEIS},
191 {"sizeof", tSIZEOF},
192/* ... */
193 {"string", tSTRING},
194 {"struct", tSTRUCT},
195 {"switch", tSWITCH},
196 {"switch_is", tSWITCHIS},
197 {"switch_type", tSWITCHTYPE},
198/* ... */
199 {"typedef", tTYPEDEF},
200 {"union", tUNION},
201/* ... */
202 {"unique", tUNIQUE},
203 {"unsigned", tUNSIGNED},
204/* ... */
205 {"uuid", tUUID},
206 {"v1_enum", tV1ENUM},
207/* ... */
208 {"version", tVERSION},
209 {"void", tVOID},
210 {"wchar_t", tWCHAR},
211 {"wire_marshal", tWIREMARSHAL},
212 {NULL}
213};
214
215static int kw_token(const char *kw)
216{
217 int i;
218 for (i=0; keywords[i].kw; i++)
219 if (strcmp(kw, keywords[i].kw) == 0)
220 return keywords[i].token;
221 yylval.str = xstrdup(kw);
222 return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
223}
224
225static void addcchar(char c)
226{
227 if(cbufidx >= cbufalloc)
228 {
229 cbufalloc += 1024;
230 cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
231 if(cbufalloc > 65536)
232 yywarning("Reallocating string buffer larger than 64kB");
233 }
234 cbuffer[cbufidx++] = c;
235}
236
237static char *get_buffered_cstring(void)
238{
239 addcchar(0);
240 return xstrdup(cbuffer);
241}
242
243static void pop_import(void)
244{
245 int ptr = import_stack_ptr-1;
246
247 fclose(yyin);
248 yy_delete_buffer( YY_CURRENT_BUFFER );
249 yy_switch_to_buffer( import_stack[ptr].state );
250 if (temp_name) {
251 unlink(temp_name);
252 free(temp_name);
253 }
254 temp_name = import_stack[ptr].temp_name;
255 import_stack_ptr--;
256}
257
258struct imports {
259 char *name;
260 struct imports *next;
261} *first_import;
262
263void do_import(char *fname)
264{
265 FILE *f;
266 char *hname, *path;
267 struct imports *import;
268 int ptr = import_stack_ptr;
269 int ret;
270
271 if (!parse_only) {
272 hname = dup_basename(fname, ".idl");
273 strcat(hname, ".h");
274
275 fprintf(header, "#include \"%s\"\n", hname);
276 free(hname);
277 }
278
279 import = first_import;
280 while (import && strcmp(import->name, fname))
281 import = import->next;
282 if (import) return; /* already imported */
283
284 import = xmalloc(sizeof(struct imports));
285 import->name = xstrdup(fname);
286 import->next = first_import;
287 first_import = import;
288
289 if (!(path = wpp_find_include( fname, 1 )))
290 yyerror("Unable to open include file %s", fname);
291
292 import_stack[ptr].temp_name = temp_name;
293 import_stack_ptr++;
294
295 ret = wpp_parse_temp( path, &temp_name );
296 free( path );
297 if (ret) exit(1);
298
299 if((f = fopen(temp_name, "r")) == NULL)
300 yyerror("Unable to open %s", temp_name);
301
302 import_stack[ptr].state = YY_CURRENT_BUFFER;
303 yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
304}
305
306void abort_import(void)
307{
308 int ptr;
309
310 for (ptr=0; ptr<import_stack_ptr; ptr++)
311 unlink(import_stack[ptr].temp_name);
312}