Commit 772f3af9 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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.
parent cc33f6c8
...@@ -39,6 +39,7 @@ int parser_lex(void); ...@@ -39,6 +39,7 @@ int parser_lex(void);
extern int import_stack_ptr; extern int import_stack_ptr;
int do_import(char *fname); int do_import(char *fname);
void abort_import(void); void abort_import(void);
void pop_import(void);
#define parse_only import_stack_ptr #define parse_only import_stack_ptr
......
...@@ -79,8 +79,6 @@ struct { ...@@ -79,8 +79,6 @@ struct {
} import_stack[MAX_IMPORT_DEPTH]; } import_stack[MAX_IMPORT_DEPTH];
int import_stack_ptr = 0; int import_stack_ptr = 0;
static void pop_import(void);
UUID *parse_uuid(const char *u) UUID *parse_uuid(const char *u)
{ {
UUID* uuid = xmalloc(sizeof(UUID)); UUID* uuid = xmalloc(sizeof(UUID));
...@@ -166,10 +164,8 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY; ...@@ -166,10 +164,8 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
<INITIAL,ATTR>\>\> return SHR; <INITIAL,ATTR>\>\> return SHR;
<INITIAL,ATTR>. return yytext[0]; <INITIAL,ATTR>. return yytext[0];
<<EOF>> { <<EOF>> {
if (import_stack_ptr) { if (import_stack_ptr)
pop_import();
return aEOF; return aEOF;
}
else yyterminate(); else yyterminate();
} }
%% %%
...@@ -367,7 +363,7 @@ static char *get_buffered_cstring(void) ...@@ -367,7 +363,7 @@ static char *get_buffered_cstring(void)
return xstrdup(cbuffer); return xstrdup(cbuffer);
} }
static void pop_import(void) void pop_import(void)
{ {
int ptr = import_stack_ptr-1; int ptr = import_stack_ptr-1;
......
...@@ -267,6 +267,7 @@ static void check_all_user_types(ifref_list_t *ifaces); ...@@ -267,6 +267,7 @@ static void check_all_user_types(ifref_list_t *ifaces);
%type <num> pointer_type version %type <num> pointer_type version
%type <str> libraryhdr %type <str> libraryhdr
%type <uuid> uuid_string %type <uuid> uuid_string
%type <num> import_start
%left ',' %left ','
%right '?' ':' %right '?' ':'
...@@ -328,8 +329,11 @@ int_statements: { $$ = NULL; } ...@@ -328,8 +329,11 @@ int_statements: { $$ = NULL; }
| int_statements statement { $$ = $1; } | int_statements statement { $$ = $1; }
; ;
statement: ';' {} semicolon_opt:
| constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } | ';'
;
statement: constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
| cppquote {} | cppquote {}
| enumdef ';' { if (!parse_only && do_header) { | enumdef ';' { if (!parse_only && do_header) {
write_type_def_or_decl(header, $1, FALSE, NULL); write_type_def_or_decl(header, $1, FALSE, NULL);
...@@ -354,12 +358,17 @@ statement: ';' {} ...@@ -354,12 +358,17 @@ statement: ';' {}
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
; ;
import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
if (!do_import($2)) yychar = aEOF; } $$ = do_import($2);
if (!$$) yychar = aEOF;
}
; ;
import: import_start imp_statements aEOF {}
import: import_start imp_statements aEOF
{ if ($1) pop_import(); }
; ;
importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } importlib: tIMPORTLIB '(' aSTRING ')'
semicolon_opt { if(!parse_only) add_importlib($3); }
; ;
libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
...@@ -369,7 +378,8 @@ library_start: attributes libraryhdr '{' { if (!parse_only) start_typelib($2, $1 ...@@ -369,7 +378,8 @@ library_start: attributes libraryhdr '{' { if (!parse_only) start_typelib($2, $1
if (!parse_only && do_idfile) write_libid($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; } m_args: { $$ = NULL; }
...@@ -726,7 +736,8 @@ coclasshdr: attributes coclass { $$ = $2; ...@@ -726,7 +736,8 @@ coclasshdr: attributes coclass { $$ = $2;
} }
; ;
coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
{ $$ = $1;
$$->ifaces = $3; $$->ifaces = $3;
$$->defined = TRUE; $$->defined = TRUE;
} }
...@@ -774,7 +785,7 @@ dispinterfacedef: dispinterfacehdr '{' ...@@ -774,7 +785,7 @@ dispinterfacedef: dispinterfacehdr '{'
if (!parse_only && do_idfile) write_diid($$); if (!parse_only && do_idfile) write_diid($$);
} }
| dispinterfacehdr | dispinterfacehdr
'{' interface ';' '}' { $$ = $1; '{' interface ';' '}' { $$ = $1;
$$->fields = $3->fields; $$->fields = $3->fields;
$$->funcs = $3->funcs; $$->funcs = $3->funcs;
if (!parse_only && do_header) write_dispinterface($$); if (!parse_only && do_header) write_dispinterface($$);
...@@ -802,7 +813,7 @@ interfacehdr: attributes interface { $$.interface = $2; ...@@ -802,7 +813,7 @@ interfacehdr: attributes interface { $$.interface = $2;
; ;
interfacedef: interfacehdr inherit interfacedef: interfacehdr inherit
'{' int_statements '}' { $$ = $1.interface; '{' int_statements '}' semicolon_opt { $$ = $1.interface;
$$->ref = $2; $$->ref = $2;
$$->funcs = $4; $$->funcs = $4;
compute_method_indexes($$); compute_method_indexes($$);
...@@ -814,7 +825,8 @@ interfacedef: interfacehdr inherit ...@@ -814,7 +825,8 @@ interfacedef: interfacehdr inherit
/* MIDL is able to import the definition of a base class from inside the /* 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 */ * definition of a derived class, I'll try to support it with this rule */
| interfacehdr ':' aIDENTIFIER | interfacehdr ':' aIDENTIFIER
'{' import int_statements '}' { $$ = $1.interface; '{' import int_statements '}'
semicolon_opt { $$ = $1.interface;
$$->ref = find_type2($3, 0); $$->ref = find_type2($3, 0);
if (!$$->ref) error_loc("base class '%s' not found in import\n", $3); if (!$$->ref) error_loc("base class '%s' not found in import\n", $3);
$$->funcs = $6; $$->funcs = $6;
...@@ -824,7 +836,7 @@ interfacedef: interfacehdr inherit ...@@ -824,7 +836,7 @@ interfacedef: interfacehdr inherit
if (!parse_only && do_idfile) write_iid($$); if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default; pointer_default = $1.old_pointer_default;
} }
| dispinterfacedef { $$ = $1; } | dispinterfacedef semicolon_opt { $$ = $1; }
; ;
interfacedec: interfacedec:
...@@ -841,7 +853,8 @@ modulehdr: attributes module { $$ = $2; ...@@ -841,7 +853,8 @@ modulehdr: attributes module { $$ = $2;
} }
; ;
moduledef: modulehdr '{' int_statements '}' { $$ = $1; moduledef: modulehdr '{' int_statements '}'
semicolon_opt { $$ = $1;
$$->funcs = $3; $$->funcs = $3;
/* FIXME: if (!parse_only && do_header) write_module($$); */ /* FIXME: if (!parse_only && do_header) write_module($$); */
} }
......
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