widl: Be more strict about where semicolons can appear in IDL files.
In particular, don't allow them after cpp_quote and without a statement. Update the rules for importlib, library definition, dispinterface definition, interface definition, coclass definition and module definition to optionally allow a semicolon postfix. Call pop_import from the parser instead of the lexer to ensure that pop_import is only called after the last statement in the imported file has been parsed.
This commit is contained in:
parent
cc33f6c8a5
commit
772f3af9f0
|
@ -39,6 +39,7 @@ int parser_lex(void);
|
|||
extern int import_stack_ptr;
|
||||
int do_import(char *fname);
|
||||
void abort_import(void);
|
||||
void pop_import(void);
|
||||
|
||||
#define parse_only import_stack_ptr
|
||||
|
||||
|
|
|
@ -79,8 +79,6 @@ struct {
|
|||
} import_stack[MAX_IMPORT_DEPTH];
|
||||
int import_stack_ptr = 0;
|
||||
|
||||
static void pop_import(void);
|
||||
|
||||
UUID *parse_uuid(const char *u)
|
||||
{
|
||||
UUID* uuid = xmalloc(sizeof(UUID));
|
||||
|
@ -166,10 +164,8 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
|
|||
<INITIAL,ATTR>\>\> return SHR;
|
||||
<INITIAL,ATTR>. return yytext[0];
|
||||
<<EOF>> {
|
||||
if (import_stack_ptr) {
|
||||
pop_import();
|
||||
if (import_stack_ptr)
|
||||
return aEOF;
|
||||
}
|
||||
else yyterminate();
|
||||
}
|
||||
%%
|
||||
|
@ -367,7 +363,7 @@ static char *get_buffered_cstring(void)
|
|||
return xstrdup(cbuffer);
|
||||
}
|
||||
|
||||
static void pop_import(void)
|
||||
void pop_import(void)
|
||||
{
|
||||
int ptr = import_stack_ptr-1;
|
||||
|
||||
|
|
|
@ -267,6 +267,7 @@ static void check_all_user_types(ifref_list_t *ifaces);
|
|||
%type <num> pointer_type version
|
||||
%type <str> libraryhdr
|
||||
%type <uuid> uuid_string
|
||||
%type <num> import_start
|
||||
|
||||
%left ','
|
||||
%right '?' ':'
|
||||
|
@ -328,8 +329,11 @@ int_statements: { $$ = NULL; }
|
|||
| int_statements statement { $$ = $1; }
|
||||
;
|
||||
|
||||
statement: ';' {}
|
||||
| constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
|
||||
semicolon_opt:
|
||||
| ';'
|
||||
;
|
||||
|
||||
statement: constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
|
||||
| cppquote {}
|
||||
| enumdef ';' { if (!parse_only && do_header) {
|
||||
write_type_def_or_decl(header, $1, FALSE, NULL);
|
||||
|
@ -354,12 +358,17 @@ statement: ';' {}
|
|||
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
|
||||
;
|
||||
import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
|
||||
if (!do_import($2)) yychar = aEOF; }
|
||||
;
|
||||
import: import_start imp_statements aEOF {}
|
||||
$$ = do_import($2);
|
||||
if (!$$) yychar = aEOF;
|
||||
}
|
||||
;
|
||||
|
||||
importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); }
|
||||
import: import_start imp_statements aEOF
|
||||
{ if ($1) pop_import(); }
|
||||
;
|
||||
|
||||
importlib: tIMPORTLIB '(' aSTRING ')'
|
||||
semicolon_opt { if(!parse_only) add_importlib($3); }
|
||||
;
|
||||
|
||||
libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
|
||||
|
@ -369,7 +378,8 @@ library_start: attributes libraryhdr '{' { if (!parse_only) start_typelib($2, $1
|
|||
if (!parse_only && do_idfile) write_libid($2, $1);
|
||||
}
|
||||
;
|
||||
librarydef: library_start imp_statements '}' { if (!parse_only) end_typelib(); }
|
||||
librarydef: library_start imp_statements '}'
|
||||
semicolon_opt { if (!parse_only) end_typelib(); }
|
||||
;
|
||||
|
||||
m_args: { $$ = NULL; }
|
||||
|
@ -726,7 +736,8 @@ coclasshdr: attributes coclass { $$ = $2;
|
|||
}
|
||||
;
|
||||
|
||||
coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1;
|
||||
coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
|
||||
{ $$ = $1;
|
||||
$$->ifaces = $3;
|
||||
$$->defined = TRUE;
|
||||
}
|
||||
|
@ -774,7 +785,7 @@ dispinterfacedef: dispinterfacehdr '{'
|
|||
if (!parse_only && do_idfile) write_diid($$);
|
||||
}
|
||||
| dispinterfacehdr
|
||||
'{' interface ';' '}' { $$ = $1;
|
||||
'{' interface ';' '}' { $$ = $1;
|
||||
$$->fields = $3->fields;
|
||||
$$->funcs = $3->funcs;
|
||||
if (!parse_only && do_header) write_dispinterface($$);
|
||||
|
@ -802,7 +813,7 @@ interfacehdr: attributes interface { $$.interface = $2;
|
|||
;
|
||||
|
||||
interfacedef: interfacehdr inherit
|
||||
'{' int_statements '}' { $$ = $1.interface;
|
||||
'{' int_statements '}' semicolon_opt { $$ = $1.interface;
|
||||
$$->ref = $2;
|
||||
$$->funcs = $4;
|
||||
compute_method_indexes($$);
|
||||
|
@ -814,7 +825,8 @@ interfacedef: interfacehdr inherit
|
|||
/* MIDL is able to import the definition of a base class from inside the
|
||||
* definition of a derived class, I'll try to support it with this rule */
|
||||
| interfacehdr ':' aIDENTIFIER
|
||||
'{' import int_statements '}' { $$ = $1.interface;
|
||||
'{' import int_statements '}'
|
||||
semicolon_opt { $$ = $1.interface;
|
||||
$$->ref = find_type2($3, 0);
|
||||
if (!$$->ref) error_loc("base class '%s' not found in import\n", $3);
|
||||
$$->funcs = $6;
|
||||
|
@ -824,7 +836,7 @@ interfacedef: interfacehdr inherit
|
|||
if (!parse_only && do_idfile) write_iid($$);
|
||||
pointer_default = $1.old_pointer_default;
|
||||
}
|
||||
| dispinterfacedef { $$ = $1; }
|
||||
| dispinterfacedef semicolon_opt { $$ = $1; }
|
||||
;
|
||||
|
||||
interfacedec:
|
||||
|
@ -841,7 +853,8 @@ modulehdr: attributes module { $$ = $2;
|
|||
}
|
||||
;
|
||||
|
||||
moduledef: modulehdr '{' int_statements '}' { $$ = $1;
|
||||
moduledef: modulehdr '{' int_statements '}'
|
||||
semicolon_opt { $$ = $1;
|
||||
$$->funcs = $3;
|
||||
/* FIXME: if (!parse_only && do_header) write_module($$); */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue