widl: Generate header files from the parse tree instead of using hooks in the parser.

This commit is contained in:
Rob Shearman 2008-12-29 12:06:35 +00:00 committed by Alexandre Julliard
parent bf5a9cb61e
commit 6b955b514d
9 changed files with 266 additions and 176 deletions

View File

@ -205,7 +205,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
switch (t->type) {
case RPC_FC_ENUM16:
case RPC_FC_ENUM32:
if (!declonly && t->defined && !t->written && !t->ignore) {
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "enum %s {\n", t->name);
else fprintf(h, "enum {\n");
t->written = TRUE;
@ -223,7 +223,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_ENCAPSULATED_UNION:
if (!declonly && t->defined && !t->written && !t->ignore) {
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "struct %s {\n", t->name);
else fprintf(h, "struct {\n");
t->written = TRUE;
@ -238,7 +238,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "struct %s", t->name ? t->name : "");
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
if (!declonly && t->defined && !t->written && !t->ignore) {
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "union %s {\n", t->name);
else fprintf(h, "union {\n");
t->written = TRUE;
@ -426,7 +426,7 @@ void check_for_additional_prototype_types(const var_list_t *list)
}
}
void write_user_types(void)
static void write_user_types(FILE *header)
{
user_type_t *ut;
LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
@ -439,7 +439,7 @@ void write_user_types(void)
}
}
void write_context_handle_rundowns(void)
static void write_context_handle_rundowns(FILE *header)
{
context_handle_t *ch;
LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry)
@ -449,7 +449,7 @@ void write_context_handle_rundowns(void)
}
}
void write_generic_handle_routines(void)
static void write_generic_handle_routines(FILE *header)
{
generic_handle_t *gh;
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
@ -460,7 +460,7 @@ void write_generic_handle_routines(void)
}
}
void write_typedef(type_t *type)
static void write_typedef(FILE *header, type_t *type)
{
fprintf(header, "typedef ");
write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name);
@ -485,7 +485,7 @@ int is_const_decl(const var_t *var)
return FALSE;
}
void write_declaration(const var_t *v, int is_in_interface)
static void write_declaration(FILE *header, const var_t *v)
{
if (is_const_decl(v) && v->eval)
{
@ -493,7 +493,7 @@ void write_declaration(const var_t *v, int is_in_interface)
write_expr(header, v->eval, 0, 1, NULL, NULL, "");
fprintf(header, ")\n\n");
}
else if (v->type->type != RPC_FC_FUNCTION || !is_in_interface)
else
{
switch (v->stgclass)
{
@ -512,7 +512,7 @@ void write_declaration(const var_t *v, int is_in_interface)
}
}
void write_library(const typelib_t *typelib)
static void write_library(FILE *header, const typelib_t *typelib)
{
const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
fprintf(header, "\n");
@ -846,55 +846,28 @@ void write_local_stubs(const statement_list_t *stmts)
fclose(local_stubs);
}
static void write_function_proto(FILE *header, const type_t *iface, const func_t *fun, const char *prefix)
static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
{
var_t *def = fun->def;
const char *callconv = get_attrp(def->type->attrs, ATTR_CALLCONV);
const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
/* FIXME: do we need to handle call_as? */
write_type_decl_left(header, get_func_return_type(fun));
write_type_decl_left(header, fun->type->ref);
fprintf(header, " ");
if (callconv) fprintf(header, "%s ", callconv);
fprintf(header, "%s%s(\n", prefix, get_name(def));
if (fun->args)
write_args(header, fun->args, iface->name, 0, TRUE);
fprintf(header, "%s%s(\n", prefix, get_name(fun));
if (fun->type->details.function->args)
write_args(header, fun->type->details.function->args, iface->name, 0, TRUE);
else
fprintf(header, " void");
fprintf(header, ");\n\n");
}
static void write_function_protos(FILE *header, const type_t *iface)
static void write_forward(FILE *header, type_t *iface)
{
const func_t *cur;
int prefixes_differ = strcmp(prefix_client, prefix_server);
if (!iface->funcs) return;
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
{
if (prefixes_differ) {
fprintf(header, "/* client prototype */\n");
write_function_proto(header, iface, cur, prefix_client);
fprintf(header, "/* server prototype */\n");
}
write_function_proto(header, iface, cur, prefix_server);
}
}
void write_forward(type_t *iface)
{
/* C/C++ forwards should only be written for object interfaces, so if we
* have a full definition we only write one if we find [object] among the
* attributes - however, if we don't have a full definition at this point
* (i.e. this is an IDL forward), then we also assume that it is an object
* interface, since non-object interfaces shouldn't need forwards */
if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
&& !iface->written) {
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name);
fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name);
fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name);
fprintf(header, "#endif\n\n" );
iface->written = TRUE;
}
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name);
fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name);
fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name);
fprintf(header, "#endif\n\n" );
}
static void write_iface_guid(FILE *header, const type_t *iface)
@ -1031,22 +1004,7 @@ static void write_rpc_interface_end(FILE *header, const type_t *iface)
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
}
void write_interface(type_t *iface)
{
if (is_attr(iface->attrs, ATTR_DISPINTERFACE) || is_object(iface->attrs))
{
write_com_interface_start(header, iface);
write_com_interface_end(header, iface);
}
else
{
write_rpc_interface_start(header, iface);
write_function_protos(header, iface);
write_rpc_interface_end(header, iface);
}
}
void write_coclass(type_t *cocl)
static void write_coclass(FILE *header, type_t *cocl)
{
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s coclass\n", cocl->name);
@ -1055,7 +1013,7 @@ void write_coclass(type_t *cocl)
fprintf(header, "\n");
}
void write_coclass_forward(type_t *cocl)
static void write_coclass_forward(FILE *header, type_t *cocl)
{
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name);
fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name);
@ -1063,7 +1021,7 @@ void write_coclass_forward(type_t *cocl)
fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
}
void write_import(const char *fname)
static void write_import(FILE *header, const char *fname)
{
char *hname, *p;
@ -1074,3 +1032,194 @@ void write_import(const char *fname)
fprintf(header, "#include <%s>\n", hname);
free(hname);
}
static void write_imports(FILE *header, const statement_list_t *stmts)
{
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
write_imports(header, stmt->u.type->stmts);
break;
case STMT_TYPEREF:
case STMT_IMPORTLIB:
/* not included in header */
break;
case STMT_IMPORT:
write_import(header, stmt->u.str);
break;
case STMT_TYPEDEF:
case STMT_MODULE:
case STMT_CPPQUOTE:
case STMT_DECLARATION:
/* not processed here */
break;
case STMT_LIBRARY:
write_imports(header, stmt->u.lib->stmts);
break;
}
}
}
static void write_forward_decls(FILE *header, const statement_list_t *stmts)
{
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
{
if (is_object(stmt->u.type->attrs) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE))
write_forward(header, stmt->u.type);
}
else if (stmt->u.type->type == RPC_FC_COCLASS)
write_coclass_forward(header, stmt->u.type);
break;
case STMT_TYPEREF:
case STMT_IMPORTLIB:
/* not included in header */
break;
case STMT_IMPORT:
case STMT_TYPEDEF:
case STMT_MODULE:
case STMT_CPPQUOTE:
case STMT_DECLARATION:
/* not processed here */
break;
case STMT_LIBRARY:
write_forward_decls(header, stmt->u.lib->stmts);
break;
}
}
}
static void write_header_stmts(FILE *header, const statement_list_t *stmts, const type_t *iface, int ignore_funcs)
{
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
{
type_t *iface = stmt->u.type;
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type->attrs))
{
write_com_interface_start(header, iface);
write_header_stmts(header, iface->stmts, stmt->u.type, TRUE);
write_com_interface_end(header, iface);
}
else
{
write_rpc_interface_start(header, iface);
write_header_stmts(header, iface->stmts, iface, FALSE);
write_rpc_interface_end(header, iface);
}
}
else if (stmt->u.type->type == RPC_FC_COCLASS)
write_coclass(header, stmt->u.type);
else
{
write_type_def_or_decl(header, stmt->u.type, FALSE, NULL);
fprintf(header, ";\n\n");
}
break;
case STMT_TYPEREF:
/* FIXME: shouldn't write out forward declarations for undefined
* interfaces but a number of our IDL files depend on this */
if (stmt->u.type->type == RPC_FC_IP && !stmt->u.type->written)
write_forward(header, stmt->u.type);
break;
case STMT_IMPORTLIB:
case STMT_MODULE:
/* not included in header */
break;
case STMT_IMPORT:
/* not processed here */
break;
case STMT_TYPEDEF:
{
const type_list_t *type_entry = stmt->u.type_list;
for (; type_entry; type_entry = type_entry->next)
write_typedef(header, type_entry->type);
break;
}
case STMT_LIBRARY:
write_library(header, stmt->u.lib);
write_header_stmts(header, stmt->u.lib->stmts, NULL, FALSE);
break;
case STMT_CPPQUOTE:
fprintf(header, "%s\n", stmt->u.str);
break;
case STMT_DECLARATION:
if (iface && stmt->u.var->type->type == RPC_FC_FUNCTION)
{
if (!ignore_funcs)
{
int prefixes_differ = strcmp(prefix_client, prefix_server);
if (prefixes_differ)
{
fprintf(header, "/* client prototype */\n");
write_function_proto(header, iface, stmt->u.var, prefix_client);
fprintf(header, "/* server prototype */\n");
}
write_function_proto(header, iface, stmt->u.var, prefix_server);
}
}
else
write_declaration(header, stmt->u.var);
break;
}
}
}
void write_header(const statement_list_t *stmts)
{
FILE *header;
if (!do_header) return;
if(!(header = fopen(header_name, "w"))) {
error("Could not open %s for output\n", header_name);
return;
}
fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
fprintf(header, "#include <rpc.h>\n" );
fprintf(header, "#include <rpcndr.h>\n\n" );
fprintf(header, "#ifndef __WIDL_%s\n", header_token);
fprintf(header, "#define __WIDL_%s\n\n", header_token);
start_cplusplus_guard(header);
fprintf(header, "/* Headers for imported files */\n\n");
write_imports(header, stmts);
fprintf(header, "\n");
/* FIXME: should be before imported file includes */
fprintf(header, "/* Forward declarations */\n\n");
write_forward_decls(header, stmts);
fprintf(header, "\n");
write_header_stmts(header, stmts, NULL, FALSE);
fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n");
write_user_types(header);
write_generic_handle_routines(header);
write_context_handle_rundowns(header);
fprintf(header, "\n");
fprintf(header, "/* End additional prototypes */\n");
fprintf(header, "\n");
end_cplusplus_guard(header);
fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
fclose(header);
}

View File

@ -47,17 +47,6 @@ extern int need_proxy_file(const statement_list_t *stmts);
extern const var_t *is_callas(const attr_list_t *list);
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
extern void write_array(FILE *h, array_dims_t *v, int field);
extern void write_import(const char *fname);
extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface);
extern void write_coclass(type_t *cocl);
extern void write_coclass_forward(type_t *cocl);
extern void write_typedef(type_t *type);
extern void write_declaration(const var_t *v, int is_in_interface);
extern void write_library(const typelib_t *typelib);
extern void write_user_types(void);
extern void write_context_handle_rundowns(void);
extern void write_generic_handle_routines(void);
extern const var_t* get_explicit_handle_var(const func_t* func);
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t* get_explicit_generic_handle_var(const func_t* func);

View File

@ -46,5 +46,6 @@ void pop_import(void);
int is_type(const char *name);
void check_functions(const type_t *iface);
func_list_t *gen_function_list(const statement_list_t *stmts);
#endif

View File

@ -69,7 +69,6 @@
#define YYERROR_VERBOSE
unsigned char pointer_default = RPC_FC_UP;
static int is_in_interface = FALSE;
static int is_object_interface = FALSE;
/* are we inside a library block? */
static int is_inside_library = FALSE;
@ -140,7 +139,6 @@ static type_t *get_type(unsigned char type, char *name, int t);
static var_t *reg_const(var_t *var);
static char *gen_name(void);
static statement_t *process_typedefs(var_list_t *names);
static void check_arg(var_t *arg);
static void check_all_user_types(const statement_list_t *stmts);
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
@ -166,9 +164,10 @@ static statement_t *make_statement_library(typelib_t *typelib);
static statement_t *make_statement_cppquote(const char *str);
static statement_t *make_statement_importlib(const char *str);
static statement_t *make_statement_module(type_t *type);
static statement_t *make_statement_typedef(var_list_t *names);
static statement_t *make_statement_import(const char *str);
static statement_t *make_statement_typedef(var_list_t *names);
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt);
#define tsENUM 1
#define tsSTRUCT 2
@ -320,7 +319,6 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
%type <declarator> declarator direct_declarator init_declarator
%type <declarator_list> declarator_list
%type <func> funcdef
%type <func_list> int_statements dispint_meths
%type <type> coclass coclasshdr coclassdef
%type <num> pointer_type version
%type <str> libraryhdr callconv cppquote importlib import t_ident
@ -328,7 +326,7 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
%type <import> import_start
%type <typelib> library_start librarydef
%type <statement> statement typedef
%type <stmt_list> gbl_statements imp_statements
%type <stmt_list> gbl_statements imp_statements int_statements dispint_meths
%left ','
%right '?' ':'
@ -349,6 +347,7 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
input: gbl_statements { fix_incomplete();
check_all_user_types($1);
write_header($1);
write_id_data($1);
write_proxies($1);
write_client($1);
@ -359,15 +358,13 @@ input: gbl_statements { fix_incomplete();
;
gbl_statements: { $$ = NULL; }
| gbl_statements interfacedec { $$ = $1; }
| gbl_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
| gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
| gbl_statements coclass ';' { $$ = $1;
reg_type($2, $2->name, 0);
if (!parse_only && do_header) write_coclass_forward($2);
}
| gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, 0);
if (!parse_only && do_header) write_coclass_forward($2);
}
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
@ -377,10 +374,9 @@ gbl_statements: { $$ = NULL; }
imp_statements: { $$ = NULL; }
| imp_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
| imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); }
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); }
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, 0);
if (!parse_only && do_header) write_coclass_forward($2);
}
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
| imp_statements statement { $$ = append_statement($1, $2); }
@ -389,7 +385,7 @@ imp_statements: { $$ = NULL; }
;
int_statements: { $$ = NULL; }
| int_statements statement { $$ = append_func_from_statement( $1, $2 ); }
| int_statements statement { $$ = append_statement($1, $2); }
;
semicolon_opt:
@ -398,15 +394,8 @@ semicolon_opt:
statement:
cppquote { $$ = make_statement_cppquote($1); }
| typedecl ';' { $$ = make_statement_type_decl($1);
if (!parse_only && do_header) {
write_type_def_or_decl(header, $1, FALSE, NULL);
fprintf(header, ";\n\n");
}
}
| declaration ';' { $$ = make_statement_declaration($1);
if (!parse_only && do_header) write_declaration($1, is_in_interface);
}
| typedecl ';' { $$ = make_statement_type_decl($1); }
| declaration ';' { $$ = make_statement_declaration($1); }
| import { $$ = make_statement_import($1); }
| typedef ';' { $$ = $1; }
;
@ -420,7 +409,7 @@ typedecl:
| attributes uniondef { $$ = $2; $$->attrs = check_union_attrs($1); }
;
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; }
;
import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
$$ = xmalloc(sizeof(struct _import_t));
@ -433,7 +422,6 @@ import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
import: import_start imp_statements aEOF { $$ = $1->name;
if ($1->import_performed) pop_import();
free($1);
if (!parse_only && do_header) write_import($$);
}
;
@ -445,7 +433,6 @@ libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
;
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
if (!parse_only) start_typelib($$);
if (!parse_only && do_header) write_library($$);
is_inside_library = TRUE;
}
;
@ -841,8 +828,6 @@ coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
coclasshdr: attributes coclass { $$ = $2;
check_def($$);
$$->attrs = check_coclass_attrs($2->name, $1);
if (!parse_only && do_header)
write_coclass($$);
}
;
@ -866,14 +851,12 @@ dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$-
;
dispinterfacehdr: attributes dispinterface { attr_t *attrs;
is_in_interface = TRUE;
is_object_interface = TRUE;
$$ = $2;
check_def($$);
attrs = make_attr(ATTR_DISPINTERFACE);
$$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
$$->defined = TRUE;
if (!parse_only && do_header) write_forward($$);
}
;
@ -890,14 +873,10 @@ dispinterfacedef: dispinterfacehdr '{'
dispint_meths
'}' { $$ = $1;
type_dispinterface_define($$, $3, $4);
if (!parse_only && do_header) write_interface($$);
is_in_interface = FALSE;
}
| dispinterfacehdr
'{' interface ';' '}' { $$ = $1;
type_dispinterface_define_from_iface($$, $3);
if (!parse_only && do_header) write_interface($$);
is_in_interface = FALSE;
}
;
@ -914,20 +893,16 @@ interfacehdr: attributes interface { $$.interface = $2;
if (is_attr($1, ATTR_POINTERDEFAULT))
pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
is_object_interface = is_object($1);
is_in_interface = TRUE;
check_def($2);
$2->attrs = check_iface_attrs($2->name, $1);
$2->defined = TRUE;
if (!parse_only && do_header) write_forward($2);
}
;
interfacedef: interfacehdr inherit
'{' int_statements '}' semicolon_opt { $$ = $1.interface;
type_interface_define($$, $2, $4);
if (!parse_only && do_header) write_interface($$);
pointer_default = $1.old_pointer_default;
is_in_interface = FALSE;
}
/* 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 */
@ -935,16 +910,14 @@ interfacedef: interfacehdr inherit
'{' import int_statements '}'
semicolon_opt { $$ = $1.interface;
type_interface_define($$, find_type_or_error2($3, 0), $6);
if (!parse_only && do_header) write_interface($$);
pointer_default = $1.old_pointer_default;
is_in_interface = FALSE;
}
| dispinterfacedef semicolon_opt { $$ = $1; }
;
interfacedec:
interface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); }
| dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); }
interface ';' { $$ = $1; }
| dispinterface ';' { $$ = $1; }
;
module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; }
@ -958,8 +931,8 @@ modulehdr: attributes module { $$ = $2;
moduledef: modulehdr '{' int_statements '}'
semicolon_opt { $$ = $1;
$$->funcs = $3;
/* FIXME: if (!parse_only && do_header) write_module($$); */
$$->stmts = $3;
$$->funcs = gen_function_list($3);
}
;
@ -1046,7 +1019,7 @@ type: tVOID { $$ = find_type_or_error("void", 0); }
typedef: tTYPEDEF m_attributes decl_spec declarator_list
{ reg_typedefs($3, $4, check_typedef_attrs($2));
$$ = process_typedefs($4);
$$ = make_statement_typedef($4);
}
;
@ -1735,7 +1708,6 @@ static func_t *make_func(var_t *def)
func_t *f = xmalloc(sizeof(func_t));
f->def = def;
f->args = def->type->details.function->args;
f->ignore = parse_only;
f->idx = -1;
return f;
}
@ -2010,6 +1982,25 @@ var_t *find_const(const char *name, int f)
return cur->var;
}
func_list_t *gen_function_list(const statement_list_t *stmts)
{
func_list_t *func_list = NULL;
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
if (stmt->type == STMT_DECLARATION)
{
var_t *var = stmt->u.var;
if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
{
check_function_attrs(var->name, var->type->attrs);
func_list = append_func(func_list, make_func(var));
}
}
}
return func_list;
}
static char *gen_name(void)
{
static const char format[] = "__WIDL_%s_generated_name_%08lX";
@ -2677,7 +2668,7 @@ static statement_t *make_statement_module(type_t *type)
return stmt;
}
static statement_t *process_typedefs(declarator_list_t *decls)
static statement_t *make_statement_typedef(declarator_list_t *decls)
{
declarator_t *decl, *next;
statement_t *stmt;
@ -2697,9 +2688,6 @@ static statement_t *process_typedefs(declarator_list_t *decls)
(*type_list)->type = type;
(*type_list)->next = NULL;
if (! parse_only && do_header)
write_typedef(type);
type_list = &(*type_list)->next;
free(decl);
free(var);
@ -2720,20 +2708,6 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
return list;
}
static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt)
{
if (stmt->type == STMT_DECLARATION)
{
var_t *var = stmt->u.var;
if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
{
check_function_attrs(var->name, var->type->attrs);
return append_func(list, make_func(stmt->u.var));
}
}
return list;
}
void init_loc_info(loc_info_t *i)
{
i->input_name = input_name ? input_name : "stdin";

View File

@ -64,13 +64,14 @@ static int compute_method_indexes(type_t *iface)
return idx;
}
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs)
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
{
iface->ref = inherit;
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->funcs = funcs;
iface->funcs = gen_function_list(stmts);
iface->details.iface->disp_props = NULL;
iface->details.iface->disp_methods = NULL;
iface->stmts = stmts;
iface->defined = TRUE;
check_functions(iface);
compute_method_indexes(iface);
@ -84,7 +85,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *me
iface->funcs = NULL;
iface->details.iface->disp_props = props;
iface->details.iface->disp_methods = methods;
iface->funcs = methods;
iface->stmts = NULL;
iface->defined = TRUE;
check_functions(iface);
compute_method_indexes(iface);

View File

@ -26,7 +26,7 @@
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs);
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);

View File

@ -213,14 +213,14 @@ static void set_everything(int x)
do_dlldata = x;
}
static void start_cplusplus_guard(FILE *fp)
void start_cplusplus_guard(FILE *fp)
{
fprintf(fp, "#ifdef __cplusplus\n");
fprintf(fp, "extern \"C\" {\n");
fprintf(fp, "#endif\n\n");
}
static void end_cplusplus_guard(FILE *fp)
void end_cplusplus_guard(FILE *fp)
{
fprintf(fp, "#ifdef __cplusplus\n");
fprintf(fp, "}\n");
@ -626,38 +626,11 @@ int main(int argc,char *argv[])
}
}
if(do_header) {
header_token = make_token(header_name);
if(!(header = fopen(header_name, "w"))) {
fprintf(stderr, "Could not open %s for output\n", header_name);
return 1;
}
fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
fprintf(header, "#include <rpc.h>\n" );
fprintf(header, "#include <rpcndr.h>\n\n" );
fprintf(header, "#ifndef __WIDL_%s\n", header_token);
fprintf(header, "#define __WIDL_%s\n", header_token);
start_cplusplus_guard(header);
}
header_token = make_token(header_name);
init_types();
ret = parser_parse();
if(do_header) {
fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n");
write_user_types();
write_generic_handle_routines();
write_context_handle_rundowns();
fprintf(header, "\n");
fprintf(header, "/* End additional prototypes */\n");
fprintf(header, "\n");
end_cplusplus_guard(header);
fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
fclose(header);
}
fclose(parser_in);
if(ret) {

View File

@ -50,6 +50,7 @@ extern int do_win64;
extern char *input_name;
extern char *header_name;
extern char *header_token;
extern char *local_stubs_name;
extern char *typelib_name;
extern char *dlldata_name;
@ -67,9 +68,7 @@ extern time_t now;
extern int line_number;
extern int char_number;
extern FILE* header;
extern FILE* idfile;
extern void write_header(const statement_list_t *stmts);
extern void write_id_data(const statement_list_t *stmts);
extern void write_proxies(const statement_list_t *stmts);
extern void write_client(const statement_list_t *stmts);
@ -77,4 +76,7 @@ extern void write_server(const statement_list_t *stmts);
extern void write_local_stubs(const statement_list_t *stmts);
extern void write_dlldata(const statement_list_t *stmts);
extern void start_cplusplus_guard(FILE *fp);
extern void end_cplusplus_guard(FILE *fp);
#endif

View File

@ -295,6 +295,7 @@ struct _type_t {
struct iface_details *iface;
} details;
func_list_t *funcs; /* interfaces and modules */
statement_list_t *stmts; /* interfaces and modules */
ifref_list_t *ifaces; /* coclasses */
unsigned long dim; /* array dimension */
expr_t *size_is, *length_is;
@ -339,7 +340,7 @@ struct _declarator_t {
struct _func_t {
var_t *def;
var_list_t *args;
int ignore, idx;
int idx;
/* parser-internal */
struct list entry;