#include <unistd.h> which is required for unlink().
[wine/multimedia.git] / tools / widl / parser.l
blobd89e479160a1d4eeec81ef2454b9d504e993657c
1 /*
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  */
21 %option stack
22 %option never-interactive
24 nl      \r?\n
25 ws      [ \f\t\r]
26 cident  [a-zA-Z_][0-9a-zA-Z_]*
27 int     [0-9]+
28 hexd    [0-9a-fA-F]
29 hex     0x{hexd}+
30 uuid    {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
32 %x QUOTE
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <assert.h>
41 #include <unistd.h>
43 #include "widl.h"
44 #include "utils.h"
45 #include "parser.h"
46 #include "../wpp/wpp.h"
48 #include "y.tab.h"
50 #define YY_USE_PROTOS
51 #define YY_NO_UNPUT
52 #define YY_NO_TOP_STATE
54 extern char *temp_name;
56 static void addcchar(char c);
57 static char *get_buffered_cstring(void);
59 static char *cbuffer;
60 static int cbufidx;
61 static int cbufalloc = 0;
63 static int kw_token(const char *kw);
65 #define MAX_IMPORT_DEPTH 10
66 struct {
67   YY_BUFFER_STATE state;
68   char *temp_name;
69 } import_stack[MAX_IMPORT_DEPTH];
70 int import_stack_ptr = 0;
72 static void pop_import(void);
77  **************************************************************************
78  * The flexer starts here
79  **************************************************************************
80  */
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);
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                         }
108 #ifndef yywrap
109 int yywrap(void)
111         return 1;
113 #endif
115 static 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}
215 static int kw_token(const char *kw)
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;
225 static void addcchar(char c)
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;
237 static char *get_buffered_cstring(void)
239         addcchar(0);
240         return xstrdup(cbuffer);
243 static void pop_import(void)
245         int ptr = import_stack_ptr-1;
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--;
258 struct imports {
259         char *name;
260         struct imports *next;
261 } *first_import;
263 void do_import(char *fname)
265         FILE *f;
266         char *hname, *path;
267         struct imports *import;
268         int ptr = import_stack_ptr;
269         int ret;
271         if (!parse_only) {
272                 hname = dup_basename(fname, ".idl");
273                 strcat(hname, ".h");
275                 fprintf(header, "#include \"%s\"\n", hname);
276                 free(hname);
277         }
279         import = first_import;
280         while (import && strcmp(import->name, fname))
281                 import = import->next;
282         if (import) return; /* already imported */
284         import = xmalloc(sizeof(struct imports));
285         import->name = xstrdup(fname);
286         import->next = first_import;
287         first_import = import;
289         if (!(path = wpp_find_include( fname, 1 )))
290             yyerror("Unable to open include file %s", fname);
292         import_stack[ptr].temp_name = temp_name;
293         import_stack_ptr++;
295         ret = wpp_parse_temp( path, &temp_name );
296         free( path );
297         if (ret) exit(1);
299         if((f = fopen(temp_name, "r")) == NULL)
300                 yyerror("Unable to open %s", temp_name);
302         import_stack[ptr].state = YY_CURRENT_BUFFER;
303         yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
306 void abort_import(void)
308         int ptr;
310         for (ptr=0; ptr<import_stack_ptr; ptr++)
311                 unlink(import_stack[ptr].temp_name);