Commit 24ded9e6 authored by Alexandre Julliard's avatar Alexandre Julliard

widl: Only recognize attribute keywords inside an attribute list.

parent 2851b31f
...@@ -31,6 +31,7 @@ hex 0x{hexd}+ ...@@ -31,6 +31,7 @@ hex 0x{hexd}+
uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12} uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
%x QUOTE %x QUOTE
%x attr
%x pp_line %x pp_line
%{ %{
...@@ -63,6 +64,7 @@ static int cbufidx; ...@@ -63,6 +64,7 @@ static int cbufidx;
static int cbufalloc = 0; static int cbufalloc = 0;
static int kw_token(const char *kw); static int kw_token(const char *kw);
static int attr_token(const char *kw);
#define MAX_IMPORT_DEPTH 10 #define MAX_IMPORT_DEPTH 10
struct { struct {
...@@ -103,7 +105,7 @@ static UUID* parse_uuid(const char*u) ...@@ -103,7 +105,7 @@ static UUID* parse_uuid(const char*u)
************************************************************************** **************************************************************************
*/ */
%% %%
<INITIAL>^{ws}*\#{ws}* yy_push_state(pp_line); <INITIAL,attr>^{ws}*\#{ws}* yy_push_state(pp_line);
<pp_line>[^\n]* { <pp_line>[^\n]* {
int lineno; int lineno;
char *cptr, *fname; char *cptr, *fname;
...@@ -123,7 +125,7 @@ static UUID* parse_uuid(const char*u) ...@@ -123,7 +125,7 @@ static UUID* parse_uuid(const char*u)
free( input_name ); free( input_name );
input_name = xstrdup(fname); input_name = xstrdup(fname);
} }
\" yy_push_state(QUOTE); cbufidx = 0; <INITIAL,attr>\" yy_push_state(QUOTE); cbufidx = 0;
<QUOTE>\" { <QUOTE>\" {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); parser_lval.str = get_buffered_cstring();
...@@ -133,25 +135,28 @@ static UUID* parse_uuid(const char*u) ...@@ -133,25 +135,28 @@ static UUID* parse_uuid(const char*u)
<QUOTE>\\\" addcchar(yytext[1]); <QUOTE>\\\" addcchar(yytext[1]);
<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]); <QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
<QUOTE>. addcchar(yytext[0]); <QUOTE>. addcchar(yytext[0]);
{uuid} { <INITIAL,attr>\[ yy_push_state(attr); return '[';
<attr>\] yy_pop_state(); return ']';
<attr>{cident} return attr_token(yytext);
<attr>{uuid} {
parser_lval.uuid = parse_uuid(yytext); parser_lval.uuid = parse_uuid(yytext);
return aUUID; return aUUID;
} }
{hex} { <INITIAL,attr>{hex} {
parser_lval.num = strtoul(yytext, NULL, 0); parser_lval.num = strtoul(yytext, NULL, 0);
return aHEXNUM; return aHEXNUM;
} }
{int} { <INITIAL,attr>{int} {
parser_lval.num = strtoul(yytext, NULL, 0); parser_lval.num = strtoul(yytext, NULL, 0);
return aNUM; return aNUM;
} }
SAFEARRAY{ws}*/\( return tSAFEARRAY; SAFEARRAY{ws}*/\( return tSAFEARRAY;
{cident} return kw_token(yytext); {cident} return kw_token(yytext);
\n line_number++; <INITIAL,attr>\n line_number++;
{ws} <INITIAL,attr>{ws}
\<\< return SHL; <INITIAL,attr>\<\< return SHL;
\>\> return SHR; <INITIAL,attr>\>\> return SHR;
. return yytext[0]; <INITIAL,attr>. return yytext[0];
<<EOF>> { <<EOF>> {
if (import_stack_ptr) { if (import_stack_ptr) {
pop_import(); pop_import();
...@@ -168,28 +173,20 @@ int parser_wrap(void) ...@@ -168,28 +173,20 @@ int parser_wrap(void)
} }
#endif #endif
static struct keyword { struct keyword {
const char *kw; const char *kw;
int token; int token;
} keywords[] = { };
static const struct keyword keywords[] = {
{"FALSE", tFALSE}, {"FALSE", tFALSE},
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__int64", tINT64}, {"__int64", tINT64},
{"__stdcall", tSTDCALL}, {"__stdcall", tSTDCALL},
{"_stdcall", tSTDCALL}, {"_stdcall", tSTDCALL},
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"boolean", tBOOLEAN}, {"boolean", tBOOLEAN},
{"broadcast", tBROADCAST},
{"byte", tBYTE}, {"byte", tBYTE},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"callback", tCALLBACK}, {"callback", tCALLBACK},
{"case", tCASE}, {"case", tCASE},
{"char", tCHAR}, {"char", tCHAR},
...@@ -197,121 +194,119 @@ static struct keyword { ...@@ -197,121 +194,119 @@ static struct keyword {
{"code", tCODE}, {"code", tCODE},
{"comm_status", tCOMMSTATUS}, {"comm_status", tCOMMSTATUS},
{"const", tCONST}, {"const", tCONST},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"control", tCONTROL}, {"control", tCONTROL},
{"cpp_quote", tCPPQUOTE}, {"cpp_quote", tCPPQUOTE},
/* ... */
{"default", tDEFAULT}, {"default", tDEFAULT},
{"defaultcollelem", tDEFAULTCOLLELEM},
{"defaultvalue", tDEFAULTVALUE},
{"defaultvtable", tDEFAULTVTABLE},
{"dispinterface", tDISPINTERFACE}, {"dispinterface", tDISPINTERFACE},
{"displaybind", tDISPLAYBIND},
{"dllname", tDLLNAME},
{"double", tDOUBLE}, {"double", tDOUBLE},
{"dual", tDUAL},
{"endpoint", tENDPOINT},
{"entry", tENTRY},
{"enum", tENUM}, {"enum", tENUM},
{"error_status_t", tERRORSTATUST}, {"error_status_t", tERRORSTATUST},
{"explicit_handle", tEXPLICITHANDLE},
{"extern", tEXTERN}, {"extern", tEXTERN},
{"float", tFLOAT}, {"float", tFLOAT},
{"handle", tHANDLE},
{"handle_t", tHANDLET}, {"handle_t", tHANDLET},
{"helpcontext", tHELPCONTEXT},
{"helpfile", tHELPFILE},
{"helpstring", tHELPSTRING},
{"helpstringcontext", tHELPSTRINGCONTEXT},
{"helpstringdll", tHELPSTRINGDLL},
{"hidden", tHIDDEN},
{"hyper", tHYPER}, {"hyper", tHYPER},
{"id", tID},
{"idempotent", tIDEMPOTENT},
/* ... */
{"iid_is", tIIDIS},
{"immediatebind", tIMMEDIATEBIND},
{"implicit_handle", tIMPLICITHANDLE},
{"import", tIMPORT}, {"import", tIMPORT},
{"importlib", tIMPORTLIB}, {"importlib", tIMPORTLIB},
{"in", tIN},
{"in_line", tINLINE}, {"in_line", tINLINE},
{"input_sync", tINPUTSYNC},
{"int", tINT}, {"int", tINT},
/* ... */
{"interface", tINTERFACE}, {"interface", tINTERFACE},
{"lcid", tLCID},
{"length_is", tLENGTHIS},
{"library", tLIBRARY}, {"library", tLIBRARY},
/* ... */
{"local", tLOCAL},
{"long", tLONG}, {"long", tLONG},
/* ... */
{"methods", tMETHODS}, {"methods", tMETHODS},
/* ... */
{"module", tMODULE}, {"module", tMODULE},
/* ... */
{"nonbrowsable", tNONBROWSABLE},
{"noncreatable", tNONCREATABLE},
{"nonextensible", tNONEXTENSIBLE},
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
/* ... */
{"optional", tOPTIONAL},
{"out", tOUT},
/* ... */
{"pointer_default", tPOINTERDEFAULT},
/* ... */
{"properties", tPROPERTIES}, {"properties", tPROPERTIES},
{"propget", tPROPGET},
{"propput", tPROPPUT},
{"propputref", tPROPPUTREF},
{"ptr", tPTR},
/* ... */
{"public", tPUBLIC},
{"range", tRANGE},
/* ... */
{"readonly", tREADONLY},
{"ref", tREF},
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
/* ... */
{"short", tSHORT}, {"short", tSHORT},
{"signed", tSIGNED}, {"signed", tSIGNED},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF}, {"sizeof", tSIZEOF},
{"small", tSMALL}, {"small", tSMALL},
/* ... */
{"source", tSOURCE},
/* ... */
{"string", tSTRING},
{"struct", tSTRUCT}, {"struct", tSTRUCT},
{"switch", tSWITCH}, {"switch", tSWITCH},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
/* ... */
{"transmit_as", tTRANSMITAS},
{"typedef", tTYPEDEF}, {"typedef", tTYPEDEF},
{"union", tUNION}, {"union", tUNION},
/* ... */
{"unique", tUNIQUE},
{"unsigned", tUNSIGNED}, {"unsigned", tUNSIGNED},
/* ... */
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
/* ... */
{"vararg", tVARARG},
{"version", tVERSION},
{"void", tVOID}, {"void", tVOID},
{"wchar_t", tWCHAR}, {"wchar_t", tWCHAR},
{"wire_marshal", tWIREMARSHAL},
}; };
#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
/* keywords only recognized in attribute lists */
static const struct keyword attr_keywords[] =
{
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"broadcast", tBROADCAST},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"defaultcollelem", tDEFAULTCOLLELEM},
{"defaultvalue", tDEFAULTVALUE},
{"defaultvtable", tDEFAULTVTABLE},
{"displaybind", tDISPLAYBIND},
{"dllname", tDLLNAME},
{"dual", tDUAL},
{"endpoint", tENDPOINT},
{"entry", tENTRY},
{"explicit_handle", tEXPLICITHANDLE},
{"handle", tHANDLE},
{"helpcontext", tHELPCONTEXT},
{"helpfile", tHELPFILE},
{"helpstring", tHELPSTRING},
{"helpstringcontext", tHELPSTRINGCONTEXT},
{"helpstringdll", tHELPSTRINGDLL},
{"hidden", tHIDDEN},
{"id", tID},
{"idempotent", tIDEMPOTENT},
{"iid_is", tIIDIS},
{"immediatebind", tIMMEDIATEBIND},
{"implicit_handle", tIMPLICITHANDLE},
{"in", tIN},
{"input_sync", tINPUTSYNC},
{"lcid", tLCID},
{"length_is", tLENGTHIS},
{"local", tLOCAL},
{"nonbrowsable", tNONBROWSABLE},
{"noncreatable", tNONCREATABLE},
{"nonextensible", tNONEXTENSIBLE},
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
{"optional", tOPTIONAL},
{"out", tOUT},
{"pointer_default", tPOINTERDEFAULT},
{"propget", tPROPGET},
{"propput", tPROPPUT},
{"propputref", tPROPPUTREF},
{"ptr", tPTR},
{"public", tPUBLIC},
{"range", tRANGE},
{"readonly", tREADONLY},
{"ref", tREF},
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"source", tSOURCE},
{"string", tSTRING},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
{"transmit_as", tTRANSMITAS},
{"unique", tUNIQUE},
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
{"vararg", tVARARG},
{"version", tVERSION},
{"wire_marshal", tWIREMARSHAL},
};
#define KWP(p) ((const struct keyword *)(p)) #define KWP(p) ((const struct keyword *)(p))
static int kw_cmp_func(const void *s1, const void *s2) static int kw_cmp_func(const void *s1, const void *s2)
...@@ -319,23 +314,11 @@ static int kw_cmp_func(const void *s1, const void *s2) ...@@ -319,23 +314,11 @@ static int kw_cmp_func(const void *s1, const void *s2)
return strcmp(KWP(s1)->kw, KWP(s2)->kw); return strcmp(KWP(s1)->kw, KWP(s2)->kw);
} }
#define KW_BSEARCH
static int kw_token(const char *kw) static int kw_token(const char *kw)
{ {
struct keyword key, *kwp; struct keyword key, *kwp;
key.kw = kw; key.kw = kw;
#ifdef KW_BSEARCH
kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
#else
{
int i;
for (kwp=NULL, i=0; i < NKEYWORDS; i++)
if (!kw_cmp_func(&key, &keywords[i])) {
kwp = &keywords[i];
break;
}
}
#endif
if (kwp) { if (kwp) {
parser_lval.str = xstrdup(kwp->kw); parser_lval.str = xstrdup(kwp->kw);
return kwp->token; return kwp->token;
...@@ -344,6 +327,19 @@ static int kw_token(const char *kw) ...@@ -344,6 +327,19 @@ static int kw_token(const char *kw)
return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
} }
static int attr_token(const char *kw)
{
struct keyword key, *kwp;
key.kw = kw;
kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]),
sizeof(attr_keywords[0]), kw_cmp_func);
if (kwp) {
parser_lval.str = xstrdup(kwp->kw);
return kwp->token;
}
return kw_token(kw);
}
static void addcchar(char c) static void addcchar(char c)
{ {
if(cbufidx >= cbufalloc) if(cbufidx >= cbufalloc)
......
...@@ -611,14 +611,6 @@ t_ident: { $$ = NULL; } ...@@ -611,14 +611,6 @@ t_ident: { $$ = NULL; }
ident: aIDENTIFIER { $$ = make_var($1); } ident: aIDENTIFIER { $$ = make_var($1); }
/* some "reserved words" used in attributes are also used as field names in some MS IDL files */ /* some "reserved words" used in attributes are also used as field names in some MS IDL files */
| aKNOWNTYPE { $$ = make_var($<str>1); } | aKNOWNTYPE { $$ = make_var($<str>1); }
| tASYNC { $$ = make_var($<str>1); }
| tID { $$ = make_var($<str>1); }
| tLCID { $$ = make_var($<str>1); }
| tOBJECT { $$ = make_var($<str>1); }
| tRANGE { $$ = make_var($<str>1); }
| tRETVAL { $$ = make_var($<str>1); }
| tUUID { $$ = make_var($<str>1); }
| tVERSION { $$ = make_var($<str>1); }
; ;
base_type: tBYTE { $$ = make_builtin($<str>1); } base_type: tBYTE { $$ = make_builtin($<str>1); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment