~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/tools/widl/parser.l

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /* -*-C-*-
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 %option stack
 22 %option noinput nounput noyy_top_state
 23 %option 8bit never-interactive prefix="parser_"
 24 
 25 nl      \r?\n
 26 ws      [ \f\t\r]
 27 cident  [a-zA-Z_][0-9a-zA-Z_]*
 28 u_suffix        (u|U)
 29 l_suffix        (l|L)
 30 int     [0-9]+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
 31 hexd    [0-9a-fA-F]
 32 hex     0(x|X){hexd}+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
 33 uuid    {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
 34 double  [0-9]+\.[0-9]+([eE][+-]?[0-9]+)*
 35 
 36 %x QUOTE
 37 %x WSTRQUOTE
 38 %x ATTR
 39 %x PP_LINE
 40 
 41 %{
 42 
 43 #include "config.h"
 44 
 45 #include <stdio.h>
 46 #include <stdlib.h>
 47 #include <string.h>
 48 #include <ctype.h>
 49 #include <assert.h>
 50 #include <errno.h>
 51 #include <limits.h>
 52 
 53 #ifdef HAVE_UNISTD_H
 54 #include <unistd.h>
 55 #else
 56 #define YY_NO_UNISTD_H
 57 #endif
 58 
 59 #include "widl.h"
 60 #include "utils.h"
 61 #include "parser.h"
 62 #include "wine/wpp.h"
 63 
 64 #include "parser.tab.h"
 65 
 66 extern char *temp_name;
 67 
 68 static void addcchar(char c);
 69 static char *get_buffered_cstring(void);
 70 
 71 static char *cbuffer;
 72 static int cbufidx;
 73 static int cbufalloc = 0;
 74 
 75 static int kw_token(const char *kw);
 76 static int attr_token(const char *kw);
 77 
 78 #define MAX_IMPORT_DEPTH 10
 79 struct {
 80   YY_BUFFER_STATE state;
 81   char *input_name;
 82   int   line_number;
 83   char *temp_name;
 84 } import_stack[MAX_IMPORT_DEPTH];
 85 int import_stack_ptr = 0;
 86 
 87 /* converts an integer in string form to an unsigned long and prints an error
 88  * on overflow */
 89 static unsigned long xstrtoul(const char *nptr, char **endptr, int base)
 90 {
 91     unsigned long l;
 92 
 93     errno = 0;
 94     l = strtoul(nptr, endptr, base);
 95     if (l == ULONG_MAX && errno == ERANGE)
 96         error_loc("integer constant %s is too large\n", nptr);
 97     return l;
 98 }
 99 
100 UUID *parse_uuid(const char *u)
101 {
102   UUID* uuid = xmalloc(sizeof(UUID));
103   char b[3];
104   /* it would be nice to use UuidFromStringA */
105   uuid->Data1 = strtoul(u, NULL, 16);
106   uuid->Data2 = strtoul(u+9, NULL, 16);
107   uuid->Data3 = strtoul(u+14, NULL, 16);
108   b[2] = 0;
109   memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16);
110   memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16);
111   memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16);
112   memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16);
113   memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16);
114   memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16);
115   memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16);
116   memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16);
117   return uuid;
118 }
119 
120 %}
121 
122 /*
123  **************************************************************************
124  * The flexer starts here
125  **************************************************************************
126  */
127 %%
128 <INITIAL,ATTR>^{ws}*\#{ws}*     yy_push_state(PP_LINE);
129 <PP_LINE>[^\n]*         {
130                             int lineno;
131                             char *cptr, *fname;
132                             yy_pop_state();
133                             lineno = (int)strtol(yytext, &cptr, 10);
134                             if(!lineno)
135                                 error_loc("Malformed '#...' line-directive; invalid linenumber\n");
136                             fname = strchr(cptr, '"');
137                             if(!fname)
138                                 error_loc("Malformed '#...' line-directive; missing filename\n");
139                             fname++;
140                             cptr = strchr(fname, '"');
141                             if(!cptr)
142                                 error_loc("Malformed '#...' line-directive; missing terminating \"\n");
143                             *cptr = '\0';
144                             line_number = lineno - 1;  /* We didn't read the newline */
145                             free( input_name );
146                             input_name = xstrdup(fname);
147                         }
148 <INITIAL,ATTR>\"        yy_push_state(QUOTE); cbufidx = 0;
149 <QUOTE>\"               {
150                                 yy_pop_state();
151                                 parser_lval.str = get_buffered_cstring();
152                                 return aSTRING;
153                         }
154 <INITIAL,ATTR>L\"       yy_push_state(WSTRQUOTE);
155 <WSTRQUOTE>\"           {
156                                 yy_pop_state();
157                                 parser_lval.str = get_buffered_cstring();
158                                 return aWSTRING;
159                         }
160 <QUOTE,WSTRQUOTE>\\\\   |
161 <QUOTE,WSTRQUOTE>\\\"   addcchar(yytext[1]);
162 <QUOTE,WSTRQUOTE>\\.    addcchar('\\'); addcchar(yytext[1]);
163 <QUOTE,WSTRQUOTE>.      addcchar(yytext[0]);
164 <INITIAL,ATTR>\[        yy_push_state(ATTR); return '[';
165 <ATTR>\]                yy_pop_state(); return ']';
166 <ATTR>{cident}          return attr_token(yytext);
167 <ATTR>{uuid}                    {
168                                 parser_lval.uuid = parse_uuid(yytext);
169                                 return aUUID;
170                         }
171 <INITIAL,ATTR>{hex}     {
172                                 parser_lval.num = xstrtoul(yytext, NULL, 0);
173                                 return aHEXNUM;
174                         }
175 <INITIAL,ATTR>{int}     {
176                                 parser_lval.num = xstrtoul(yytext, NULL, 0);
177                                 return aNUM;
178                         }
179 <INITIAL>{double}       {
180                                 parser_lval.dbl = strtod(yytext, NULL);
181                                 return aDOUBLE;
182                         }
183 SAFEARRAY{ws}*/\(       return tSAFEARRAY;
184 {cident}                return kw_token(yytext);
185 <INITIAL,ATTR>\n        line_number++;
186 <INITIAL,ATTR>{ws}
187 <INITIAL,ATTR>\<\<      return SHL;
188 <INITIAL,ATTR>\>\>      return SHR;
189 <INITIAL,ATTR>\-\>      return MEMBERPTR;
190 <INITIAL,ATTR>==        return EQUALITY;
191 <INITIAL,ATTR>!=        return INEQUALITY;
192 <INITIAL,ATTR>\>=       return GREATEREQUAL;
193 <INITIAL,ATTR>\<=       return LESSEQUAL;
194 <INITIAL,ATTR>\|\|      return LOGICALOR;
195 <INITIAL,ATTR>&&        return LOGICALAND;
196 <INITIAL,ATTR>\.\.\.    return ELLIPSIS;
197 <INITIAL,ATTR>.         return yytext[0];
198 <<EOF>>                 {
199                                 if (import_stack_ptr)
200                                         return aEOF;
201                                 else yyterminate();
202                         }
203 %%
204 
205 #ifndef parser_wrap
206 int parser_wrap(void)
207 {
208         return 1;
209 }
210 #endif
211 
212 struct keyword {
213         const char *kw;
214         int token;
215 };
216 
217 /* This table MUST be alphabetically sorted on the kw field */
218 static const struct keyword keywords[] = {
219         {"FALSE",                       tFALSE},
220         {"NULL",                        tNULL},
221         {"TRUE",                        tTRUE},
222         {"__cdecl",                     tCDECL},
223         {"__fastcall",                  tFASTCALL},
224         {"__int3264",                   tINT3264},
225         {"__int64",                     tINT64},
226         {"__pascal",                    tPASCAL},
227         {"__stdcall",                   tSTDCALL},
228         {"_cdecl",                      tCDECL},
229         {"_fastcall",                   tFASTCALL},
230         {"_pascal",                     tPASCAL},
231         {"_stdcall",                    tSTDCALL},
232         {"boolean",                     tBOOLEAN},
233         {"byte",                        tBYTE},
234         {"case",                        tCASE},
235         {"cdecl",                       tCDECL},
236         {"char",                        tCHAR},
237         {"coclass",                     tCOCLASS},
238         {"const",                       tCONST},
239         {"cpp_quote",                   tCPPQUOTE},
240         {"default",                     tDEFAULT},
241         {"dispinterface",               tDISPINTERFACE},
242         {"double",                      tDOUBLE},
243         {"enum",                        tENUM},
244         {"error_status_t",              tERRORSTATUST},
245         {"extern",                      tEXTERN},
246         {"float",                       tFLOAT},
247         {"handle_t",                    tHANDLET},
248         {"hyper",                       tHYPER},
249         {"import",                      tIMPORT},
250         {"importlib",                   tIMPORTLIB},
251         {"inline",                      tINLINE},
252         {"int",                         tINT},
253         {"interface",                   tINTERFACE},
254         {"library",                     tLIBRARY},
255         {"long",                        tLONG},
256         {"methods",                     tMETHODS},
257         {"module",                      tMODULE},
258         {"pascal",                      tPASCAL},
259         {"properties",                  tPROPERTIES},
260         {"register",                    tREGISTER},
261         {"short",                       tSHORT},
262         {"signed",                      tSIGNED},
263         {"sizeof",                      tSIZEOF},
264         {"small",                       tSMALL},
265         {"static",                      tSTATIC},
266         {"stdcall",                     tSTDCALL},
267         {"struct",                      tSTRUCT},
268         {"switch",                      tSWITCH},
269         {"typedef",                     tTYPEDEF},
270         {"union",                       tUNION},
271         {"unsigned",                    tUNSIGNED},
272         {"void",                        tVOID},
273         {"wchar_t",                     tWCHAR},
274 };
275 #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
276 
277 /* keywords only recognized in attribute lists
278  * This table MUST be alphabetically sorted on the kw field
279  */
280 static const struct keyword attr_keywords[] =
281 {
282         {"aggregatable",                tAGGREGATABLE},
283         {"allocate",                    tALLOCATE},
284         {"annotation",                  tANNOTATION},
285         {"appobject",                   tAPPOBJECT},
286         {"async",                       tASYNC},
287         {"async_uuid",                  tASYNCUUID},
288         {"auto_handle",                 tAUTOHANDLE},
289         {"bindable",                    tBINDABLE},
290         {"broadcast",                   tBROADCAST},
291         {"byte_count",                  tBYTECOUNT},
292         {"call_as",                     tCALLAS},
293         {"callback",                    tCALLBACK},
294         {"code",                        tCODE},
295         {"comm_status",                 tCOMMSTATUS},
296         {"context_handle",              tCONTEXTHANDLE},
297         {"context_handle_noserialize",  tCONTEXTHANDLENOSERIALIZE},
298         {"context_handle_serialize",    tCONTEXTHANDLENOSERIALIZE},
299         {"control",                     tCONTROL},
300         {"defaultcollelem",             tDEFAULTCOLLELEM},
301         {"defaultvalue",                tDEFAULTVALUE},
302         {"defaultvtable",               tDEFAULTVTABLE},
303         {"displaybind",                 tDISPLAYBIND},
304         {"dllname",                     tDLLNAME},
305         {"dual",                        tDUAL},
306         {"endpoint",                    tENDPOINT},
307         {"entry",                       tENTRY},
308         {"explicit_handle",             tEXPLICITHANDLE},
309         {"handle",                      tHANDLE},
310         {"helpcontext",                 tHELPCONTEXT},
311         {"helpfile",                    tHELPFILE},
312         {"helpstring",                  tHELPSTRING},
313         {"helpstringcontext",           tHELPSTRINGCONTEXT},
314         {"helpstringdll",               tHELPSTRINGDLL},
315         {"hidden",                      tHIDDEN},
316         {"id",                          tID},
317         {"idempotent",                  tIDEMPOTENT},
318         {"iid_is",                      tIIDIS},
319         {"immediatebind",               tIMMEDIATEBIND},
320         {"implicit_handle",             tIMPLICITHANDLE},
321         {"in",                          tIN},
322         {"in_line",                     tIN_LINE},
323         {"input_sync",                  tINPUTSYNC},
324         {"lcid",                        tLCID},
325         {"length_is",                   tLENGTHIS},
326         {"local",                       tLOCAL},
327         {"nonbrowsable",                tNONBROWSABLE},
328         {"noncreatable",                tNONCREATABLE},
329         {"nonextensible",               tNONEXTENSIBLE},
330         {"object",                      tOBJECT},
331         {"odl",                         tODL},
332         {"oleautomation",               tOLEAUTOMATION},
333         {"optional",                    tOPTIONAL},
334         {"out",                         tOUT},
335         {"pointer_default",             tPOINTERDEFAULT},
336         {"propget",                     tPROPGET},
337         {"propput",                     tPROPPUT},
338         {"propputref",                  tPROPPUTREF},
339         {"ptr",                         tPTR},
340         {"public",                      tPUBLIC},
341         {"range",                       tRANGE},
342         {"readonly",                    tREADONLY},
343         {"ref",                         tREF},
344         {"requestedit",                 tREQUESTEDIT},
345         {"restricted",                  tRESTRICTED},
346         {"retval",                      tRETVAL},
347         {"size_is",                     tSIZEIS},
348         {"source",                      tSOURCE},
349         {"strict_context_handle",       tSTRICTCONTEXTHANDLE},
350         {"string",                      tSTRING},
351         {"switch_is",                   tSWITCHIS},
352         {"switch_type",                 tSWITCHTYPE},
353         {"transmit_as",                 tTRANSMITAS},
354         {"unique",                      tUNIQUE},
355         {"uuid",                        tUUID},
356         {"v1_enum",                     tV1ENUM},
357         {"vararg",                      tVARARG},
358         {"version",                     tVERSION},
359         {"wire_marshal",                tWIREMARSHAL},
360 };
361 
362 
363 #define KWP(p) ((const struct keyword *)(p))
364 
365 static int kw_cmp_func(const void *s1, const void *s2)
366 {
367         return strcmp(KWP(s1)->kw, KWP(s2)->kw);
368 }
369 
370 static int kw_token(const char *kw)
371 {
372         struct keyword key, *kwp;
373         key.kw = kw;
374         kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
375         if (kwp) {
376                 parser_lval.str = xstrdup(kwp->kw);
377                 return kwp->token;
378         }
379         parser_lval.str = xstrdup(kw);
380         return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
381 }
382 
383 static int attr_token(const char *kw)
384 {
385         struct keyword key, *kwp;
386         key.kw = kw;
387         kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]),
388                       sizeof(attr_keywords[0]), kw_cmp_func);
389         if (kwp) {
390             parser_lval.str = xstrdup(kwp->kw);
391             return kwp->token;
392         }
393         return kw_token(kw);
394 }
395 
396 static void addcchar(char c)
397 {
398         if(cbufidx >= cbufalloc)
399         {
400                 cbufalloc += 1024;
401                 cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
402                 if(cbufalloc > 65536)
403                         parser_warning("Reallocating string buffer larger than 64kB\n");
404         }
405         cbuffer[cbufidx++] = c;
406 }
407 
408 static char *get_buffered_cstring(void)
409 {
410         addcchar(0);
411         return xstrdup(cbuffer);
412 }
413 
414 void pop_import(void)
415 {
416         int ptr = import_stack_ptr-1;
417 
418         fclose(yyin);
419         yy_delete_buffer( YY_CURRENT_BUFFER );
420         yy_switch_to_buffer( import_stack[ptr].state );
421         if (temp_name) {
422                 unlink(temp_name);
423                 free(temp_name);
424         }
425         temp_name = import_stack[ptr].temp_name;
426         input_name = import_stack[ptr].input_name;
427         line_number = import_stack[ptr].line_number;
428         import_stack_ptr--;
429 }
430 
431 struct imports {
432         char *name;
433         struct imports *next;
434 } *first_import;
435 
436 int do_import(char *fname)
437 {
438         FILE *f;
439         char *path;
440         struct imports *import;
441         int ptr = import_stack_ptr;
442         int ret;
443 
444         import = first_import;
445         while (import && strcmp(import->name, fname))
446                 import = import->next;
447         if (import) return 0; /* already imported */
448 
449         import = xmalloc(sizeof(struct imports));
450         import->name = xstrdup(fname);
451         import->next = first_import;
452         first_import = import;
453 
454         /* don't search for a file name with a path in the include directories,
455          * for compatibility with MIDL */
456         if (strchr( fname, '/' ) || strchr( fname, '\\' ))
457             path = strdup( fname );
458         else if (!(path = wpp_find_include( fname, input_name )))
459             error_loc("Unable to open include file %s\n", fname);
460 
461         import_stack[ptr].temp_name = temp_name;
462         import_stack[ptr].input_name = input_name;
463         import_stack[ptr].line_number = line_number;
464         import_stack_ptr++;
465         input_name = path;
466         line_number = 1;
467 
468         ret = wpp_parse_temp( path, NULL, &temp_name );
469         if (ret) exit(1);
470 
471         if((f = fopen(temp_name, "r")) == NULL)
472                 error_loc("Unable to open %s\n", temp_name);
473 
474         import_stack[ptr].state = YY_CURRENT_BUFFER;
475         yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
476         return 1;
477 }
478 
479 void abort_import(void)
480 {
481         int ptr;
482 
483         for (ptr=0; ptr<import_stack_ptr; ptr++)
484                 unlink(import_stack[ptr].temp_name);
485 }

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.