From df0e38c0670a40eb5892e53ffb506bb1f4bc33ba Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Thu, 24 Apr 2008 19:06:28 +0100 Subject: [PATCH] widl: Create a list of statements in the whole IDL file, instead of just a list of interfaces. --- tools/widl/client.c | 75 ++++++++------ tools/widl/header.c | 6 +- tools/widl/header.h | 6 +- tools/widl/parser.y | 211 +++++++++++++++++++++++++++++++--------- tools/widl/proxy.c | 132 ++++++++++++++++--------- tools/widl/server.c | 75 ++++++++------ tools/widl/typegen.c | 117 ++++++++++++++-------- tools/widl/typegen.h | 10 +- tools/widl/typelib.c | 14 +-- tools/widl/typelib.h | 2 +- tools/widl/widl.c | 4 +- tools/widl/widl.h | 8 +- tools/widl/widltypes.h | 31 ++++++ tools/widl/write_msft.c | 7 +- 14 files changed, 470 insertions(+), 228 deletions(-) diff --git a/tools/widl/client.c b/tools/widl/client.c index 889d2f1eab9..779492e9171 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -431,58 +431,69 @@ static void init_client(void) } -void write_client(ifref_list_t *ifaces) +static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset) +{ + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + type_t *iface = stmt->u.type; + if (!need_stub(iface)) + return; + + fprintf(client, "/*****************************************************************************\n"); + fprintf(client, " * %s interface\n", iface->name); + fprintf(client, " */\n"); + fprintf(client, "\n"); + + if (iface->funcs) + { + write_implicithandledecl(iface); + + write_clientinterfacedecl(iface); + write_stubdescdecl(iface); + write_function_stubs(iface, proc_offset); + + print_client("#if !defined(__RPC_WIN32__)\n"); + print_client("#error Invalid build platform for this stub.\n"); + print_client("#endif\n"); + + fprintf(client, "\n"); + write_stubdescriptor(iface, expr_eval_routines); + } + } + else if (stmt->type == STMT_LIBRARY) + write_client_ifaces(stmt->u.lib->stmts, expr_eval_routines, proc_offset); + } +} + +void write_client(const statement_list_t *stmts) { unsigned int proc_offset = 0; int expr_eval_routines; - ifref_t *iface; if (!do_client) return; - if (do_everything && !need_stub_files(ifaces)) + if (do_everything && !need_stub_files(stmts)) return; init_client(); if (!client) return; - write_formatstringsdecl(client, indent, ifaces, need_stub); + write_formatstringsdecl(client, indent, stmts, need_stub); expr_eval_routines = write_expr_eval_routines(client, client_token); if (expr_eval_routines) write_expr_eval_routine_list(client, client_token); write_user_quad_list(client); - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (!need_stub(iface->iface)) - continue; - - fprintf(client, "/*****************************************************************************\n"); - fprintf(client, " * %s interface\n", iface->iface->name); - fprintf(client, " */\n"); - fprintf(client, "\n"); - - if (iface->iface->funcs) - { - write_implicithandledecl(iface->iface); - - write_clientinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - write_function_stubs(iface->iface, &proc_offset); - - print_client("#if !defined(__RPC_WIN32__)\n"); - print_client("#error Invalid build platform for this stub.\n"); - print_client("#endif\n"); - - fprintf(client, "\n"); - write_stubdescriptor(iface->iface, expr_eval_routines); - } - } + write_client_ifaces(stmts, expr_eval_routines, &proc_offset); fprintf(client, "\n"); - write_procformatstring(client, ifaces, need_stub); - write_typeformatstring(client, ifaces, need_stub); + write_procformatstring(client, stmts, need_stub); + write_typeformatstring(client, stmts, need_stub); fclose(client); } diff --git a/tools/widl/header.c b/tools/widl/header.c index 3915244c879..0d7e0b2f945 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -487,11 +487,11 @@ void write_externdef(const var_t *v) fprintf(header, ";\n\n"); } -void write_library(const char *name, const attr_list_t *attr) +void write_library(const typelib_t *typelib) { - const UUID *uuid = get_attrp(attr, ATTR_UUID); + const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID); fprintf(header, "\n"); - write_guid(header, "LIBID", name, uuid); + write_guid(header, "LIBID", typelib->name, uuid); fprintf(header, "\n"); } diff --git a/tools/widl/header.h b/tools/widl/header.h index 56573285443..c663c7079bd 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -44,8 +44,8 @@ extern int is_object(const attr_list_t *list); extern int is_local(const attr_list_t *list); extern int need_stub(const type_t *iface); extern int need_proxy(const type_t *iface); -extern int need_stub_files(const ifref_list_t *ifaces); -extern int need_proxy_file(const ifref_list_t *ifaces); +extern int need_stub_files(const statement_list_t *stmts); +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); @@ -58,7 +58,7 @@ extern void write_coclass_forward(type_t *cocl); extern void write_typedef(type_t *type); extern void write_constdef(const var_t *v); extern void write_externdef(const var_t *v); -extern void write_library(const char *name, const attr_list_t *attr); +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); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 0514d9c748d..a9c7d0288c2 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -103,6 +103,7 @@ static type_t *make_class(char *name); static type_t *make_safearray(type_t *type); static type_t *make_builtin(char *name); static type_t *make_int(int sign); +static typelib_t *make_library(const char *name, const attr_list_t *attrs); static type_t *make_func_type(var_list_t *args); static void type_set_function_callconv(type_t *type, char *callconv); static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type); @@ -116,7 +117,7 @@ static int get_struct_type(var_list_t *fields); static var_t *reg_const(var_t *var); -static void write_libid(const char *name, const attr_list_t *attr); +static void write_libid(const typelib_t *typelib); static void write_clsid(type_t *cls); static void write_diid(type_t *iface); static void write_iid(type_t *iface); @@ -126,7 +127,7 @@ static char *gen_name(void); static void process_typedefs(var_list_t *names); static void check_arg(var_t *arg); static void check_functions(const type_t *iface); -static void check_all_user_types(ifref_list_t *ifaces); +static void check_all_user_types(const statement_list_t *stmts); static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs); static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_typedef_attrs(attr_list_t *attrs); @@ -138,6 +139,17 @@ static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_ const char *get_attr_display_name(enum attr_type type); static void add_explicit_handle_if_necessary(func_t *func); +static statement_t *make_statement(enum statement_type type); +static statement_t *make_statement_type_decl(type_t *type); +static statement_t *make_statement_reference(type_t *type); +static statement_t *make_statement_init_decl(var_t *var); +static statement_t *make_statement_extern(var_t *var); +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_list_t *append_statement(statement_list_t *list, statement_t *stmt); + #define tsENUM 1 #define tsSTRUCT 2 #define tsUNION 3 @@ -157,6 +169,8 @@ static void add_explicit_handle_if_necessary(func_t *func); pident_list_t *pident_list; func_t *func; func_list_t *func_list; + statement_t *statement; + statement_list_t *stmt_list; ifref_t *ifref; ifref_list_t *ifref_list; char *str; @@ -164,6 +178,7 @@ static void add_explicit_handle_if_necessary(func_t *func); unsigned int num; double dbl; interface_info_t ifinfo; + typelib_t *typelib; } %token aIDENTIFIER @@ -272,7 +287,7 @@ static void add_explicit_handle_if_necessary(func_t *func); %type enumdef structdef uniondef %type type %type coclass_int -%type gbl_statements coclass_ints +%type coclass_ints %type arg field s_field case enum constdef externdef %type m_args no_args args fields cases enums enum_list dispint_props %type m_ident t_ident ident @@ -282,9 +297,12 @@ static void add_explicit_handle_if_necessary(func_t *func); %type int_statements dispint_meths %type coclass coclasshdr coclassdef %type pointer_type version -%type libraryhdr callconv +%type libraryhdr callconv cppquote importlib %type uuid_string %type import_start +%type library_start librarydef +%type statement +%type gbl_statements imp_statements %left ',' %right '?' ':' @@ -314,33 +332,36 @@ input: gbl_statements { fix_incomplete(); gbl_statements: { $$ = NULL; } | gbl_statements interfacedec { $$ = $1; } - | gbl_statements interfacedef { $$ = append_ifref( $1, make_ifref($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 { $$ = $1; + | gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); add_typelib_entry($2); reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | gbl_statements moduledef { $$ = $1; add_typelib_entry($2); } - | gbl_statements librarydef { $$ = $1; } - | gbl_statements statement { $$ = $1; } + | gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); + add_typelib_entry($2); + } + | gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } + | gbl_statements statement { $$ = append_statement($1, $2); } ; -imp_statements: {} - | imp_statements interfacedec { if (!parse_only) add_typelib_entry($2); } - | imp_statements interfacedef { if (!parse_only) add_typelib_entry($2); } - | imp_statements coclass ';' { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements coclassdef { if (!parse_only) add_typelib_entry($2); +imp_statements: { $$ = NULL; } + | imp_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); if (!parse_only) add_typelib_entry($2); } + | imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); if (!parse_only) add_typelib_entry($2); } + | imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } + | imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); + if (!parse_only) add_typelib_entry($2); reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements moduledef { if (!parse_only) add_typelib_entry($2); } - | imp_statements statement {} - | imp_statements importlib {} - | imp_statements librarydef {} + | imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); if (!parse_only) add_typelib_entry($2); } + | imp_statements statement { $$ = append_statement($1, $2); } + | imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); } + | imp_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } ; int_statements: { $$ = NULL; } @@ -352,29 +373,36 @@ semicolon_opt: | ';' ; -statement: constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } - | cppquote {} - | enumdef ';' { if (!parse_only && do_header) { +statement: constdef ';' { $$ = make_statement_init_decl($1); + if (!parse_only && do_header) { write_constdef($1); } + } + | cppquote { $$ = make_statement_cppquote($1); } + | enumdef ';' { $$ = make_statement_type_decl($1); + if (!parse_only && do_header) { write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } - | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } - | import {} - | structdef ';' { if (!parse_only && do_header) { + | externdef ';' { $$ = make_statement_extern($1); + if (!parse_only && do_header) write_externdef($1); + } + | import { $$ = NULL; } + | structdef ';' { $$ = make_statement_type_decl($1); + if (!parse_only && do_header) { write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } - | typedef ';' {} - | uniondef ';' { if (!parse_only && do_header) { + | typedef ';' { $$ = NULL; /* FIXME */ } + | uniondef ';' { $$ = make_statement_type_decl($1); + if (!parse_only && do_header) { write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } ; -cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } +cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); } ; import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); $$ = do_import($2); @@ -387,20 +415,24 @@ import: import_start imp_statements aEOF ; importlib: tIMPORTLIB '(' aSTRING ')' - semicolon_opt { if(!parse_only) add_importlib($3); } + semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3); } ; libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } ; -library_start: attributes libraryhdr '{' { check_library_attrs($2, $1); - if (!parse_only) start_typelib($2, $1); - if (!parse_only && do_header) write_library($2, $1); - if (!parse_only && do_idfile) write_libid($2, $1); +library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1)); + if (!parse_only) start_typelib($$); + if (!parse_only && do_header) write_library($$); + if (!parse_only && do_idfile) write_libid($$); is_inside_library = TRUE; } ; librarydef: library_start imp_statements '}' - semicolon_opt { if (!parse_only) end_typelib(); is_inside_library = FALSE; } + semicolon_opt { $$ = $1; + $$->stmts = $2; + if (!parse_only) end_typelib(); + is_inside_library = FALSE; + } ; m_args: { $$ = NULL; } @@ -1457,7 +1489,7 @@ static func_t *make_func(var_t *def) static type_t *make_class(char *name) { - type_t *c = make_type(0, NULL); + type_t *c = make_type(RPC_FC_COCLASS, NULL); c->name = name; c->kind = TKIND_COCLASS; return c; @@ -1470,6 +1502,17 @@ static type_t *make_safearray(type_t *type) return make_type(pointer_default, sa); } +static typelib_t *make_library(const char *name, const attr_list_t *attrs) +{ + typelib_t *typelib = xmalloc(sizeof(*typelib)); + typelib->name = xstrdup(name); + typelib->filename = NULL; + typelib->attrs = attrs; + list_init( &typelib->entries ); + list_init( &typelib->importlibs ); + return typelib; +} + #define HASHMAX 64 static int hash_ident(const char *name) @@ -1877,10 +1920,10 @@ var_t *find_const(const char *name, int f) return cur->var; } -static void write_libid(const char *name, const attr_list_t *attr) +static void write_libid(const typelib_t *typelib) { - const UUID *uuid = get_attrp(attr, ATTR_UUID); - write_guid(idfile, "LIBID", name, uuid); + const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID); + write_guid(idfile, "LIBID", typelib->name, uuid); } static void write_clsid(type_t *cls) @@ -2462,16 +2505,21 @@ static void check_functions(const type_t *iface) } } -static void check_all_user_types(ifref_list_t *ifrefs) +static void check_all_user_types(const statement_list_t *stmts) { - const ifref_t *ifref; - const func_t *f; + const statement_t *stmt; - if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) + if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry) { - const func_list_t *fs = ifref->iface->funcs; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_additional_prototype_types(f->args); + if (stmt->type == STMT_LIBRARY) + check_all_user_types(stmt->u.lib->stmts); + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + const func_t *f; + const func_list_t *fs = stmt->u.type->funcs; + if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) + check_for_additional_prototype_types(f->args); + } } } @@ -2491,3 +2539,78 @@ int is_valid_uuid(const char *s) return s[i] == '\0'; } + +static statement_t *make_statement(enum statement_type type) +{ + statement_t *stmt = xmalloc(sizeof(*stmt)); + stmt->type = type; + return stmt; +} + +static statement_t *make_statement_type_decl(type_t *type) +{ + statement_t *stmt = make_statement(STMT_TYPE); + stmt->u.type = type; + return stmt; +} + +static statement_t *make_statement_reference(type_t *type) +{ + statement_t *stmt = make_statement(STMT_TYPEREF); + stmt->u.type = type; + return stmt; +} + +static statement_t *make_statement_init_decl(var_t *var) +{ + statement_t *stmt = make_statement(STMT_INITDECL); + stmt->u.var = var; + return stmt; +} + +static statement_t *make_statement_extern(var_t *var) +{ + statement_t *stmt = make_statement(STMT_EXTERN); + stmt->u.var = var; + return stmt; +} + +static statement_t *make_statement_library(typelib_t *typelib) +{ + statement_t *stmt = make_statement(STMT_LIBRARY); + stmt->u.lib = typelib; + return stmt; +} + +static statement_t *make_statement_cppquote(const char *str) +{ + statement_t *stmt = make_statement(STMT_CPPQUOTE); + stmt->u.str = str; + return stmt; +} + +static statement_t *make_statement_importlib(const char *str) +{ + statement_t *stmt = make_statement(STMT_IMPORTLIB); + stmt->u.str = str; + return stmt; +} + +static statement_t *make_statement_module(type_t *type) +{ + statement_t *stmt = make_statement(STMT_MODULE); + stmt->u.type = type; + return stmt; +} + +static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt) +{ + if (!stmt) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &stmt->entry ); + return list; +} diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 2fa0a4d6607..ee8db3939c1 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -89,7 +89,7 @@ static void write_stubdesc(int expr_eval_routines) print_proxy( "\n"); } -static void init_proxy(ifref_list_t *ifaces) +static void init_proxy(const statement_list_t *stmts) { if (proxy) return; if(!(proxy = fopen(proxy_name, "w"))) @@ -109,7 +109,7 @@ static void init_proxy(ifref_list_t *ifaces) print_proxy( "\n"); print_proxy( "#include \"%s\"\n", header_name); print_proxy( "\n"); - write_formatstringsdecl(proxy, indent, ifaces, need_proxy); + write_formatstringsdecl(proxy, indent, stmts, need_proxy); write_stubdescproto(); } @@ -592,14 +592,24 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset) print_proxy( "\n"); } -static int does_any_iface(const ifref_list_t *ifaces, type_pred_t pred) +static int does_any_iface(const statement_list_t *stmts, type_pred_t pred) { - ifref_t *ir; + const statement_t *stmt; - if (ifaces) - LIST_FOR_EACH_ENTRY(ir, ifaces, ifref_t, entry) - if (pred(ir->iface)) - return TRUE; + if (stmts) + LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry) + { + if (stmt->type == STMT_LIBRARY) + { + if (does_any_iface(stmt->u.lib->stmts, pred)) + return TRUE; + } + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + if (pred(stmt->u.type)) + return TRUE; + } + } return FALSE; } @@ -614,34 +624,84 @@ int need_stub(const type_t *iface) return !is_object(iface->attrs) && !is_local(iface->attrs); } -int need_proxy_file(const ifref_list_t *ifaces) +int need_proxy_file(const statement_list_t *stmts) { - return does_any_iface(ifaces, need_proxy); + return does_any_iface(stmts, need_proxy); } -int need_stub_files(const ifref_list_t *ifaces) +int need_stub_files(const statement_list_t *stmts) { - return does_any_iface(ifaces, need_stub); + return does_any_iface(stmts, need_stub); } -void write_proxies(ifref_list_t *ifaces) +static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_offset) +{ + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type == STMT_LIBRARY) + write_proxy_stmts(stmt->u.lib->stmts, proc_offset); + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + if (need_proxy(stmt->u.type)) + write_proxy(stmt->u.type, proc_offset); + } + } +} + +static void write_proxy_iface_name_format(const statement_list_t *stmts, const char *format) +{ + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type == STMT_LIBRARY) + write_proxy_iface_name_format(stmt->u.lib->stmts, format); + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + type_t *iface = stmt->u.type; + if (iface->ref && iface->funcs && need_proxy(iface)) + fprintf(proxy, format, iface->name); + } + } +} + +static void write_iid_lookup(const statement_list_t *stmts, const char *file_id, int *c) +{ + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type == STMT_LIBRARY) + write_iid_lookup(stmt->u.lib->stmts, file_id, c); + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + type_t *iface = stmt->u.type; + if(iface->ref && iface->funcs && need_proxy(iface)) + { + fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, *c); + fprintf(proxy, " {\n"); + fprintf(proxy, " *pIndex = %d;\n", *c); + fprintf(proxy, " return 1;\n"); + fprintf(proxy, " }\n"); + (*c)++; + } + } + } +} + +void write_proxies(const statement_list_t *stmts) { - ifref_t *cur; int expr_eval_routines; char *file_id = proxy_token; int c; unsigned int proc_offset = 0; if (!do_proxies) return; - if (do_everything && !need_proxy_file(ifaces)) return; + if (do_everything && !need_proxy_file(stmts)) return; - init_proxy(ifaces); + init_proxy(stmts); if(!proxy) return; - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if (need_proxy(cur->iface)) - write_proxy(cur->iface, &proc_offset); + write_proxy_stmts(stmts, &proc_offset); expr_eval_routines = write_expr_eval_routines(proxy, proxy_token); if (expr_eval_routines) @@ -653,36 +713,26 @@ void write_proxies(ifref_list_t *ifaces) print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); print_proxy( "#endif\n"); print_proxy( "\n"); - write_procformatstring(proxy, ifaces, need_proxy); - write_typeformatstring(proxy, ifaces, need_proxy); + write_procformatstring(proxy, stmts, need_proxy); + write_typeformatstring(proxy, stmts, need_proxy); fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id); fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); - + write_proxy_iface_name_format(stmts, " (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n"); fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id); fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " (const CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); + write_proxy_iface_name_format(stmts, " (const CInterfaceStubVtbl*)&_%sStubVtbl,\n"); fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " \"%s\",\n", cur->iface->name); + write_proxy_iface_name_format(stmts, " \"%s\",\n"); fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); @@ -692,17 +742,7 @@ void write_proxies(ifref_list_t *ifaces) fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id); fprintf(proxy, "{\n"); c = 0; - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - { - fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); - fprintf(proxy, " {\n"); - fprintf(proxy, " *pIndex = %d;\n", c); - fprintf(proxy, " return 1;\n"); - fprintf(proxy, " }\n"); - c++; - } + write_iid_lookup(stmts, file_id, &c); fprintf(proxy, " return 0;\n"); fprintf(proxy, "}\n"); fprintf(proxy, "\n"); diff --git a/tools/widl/server.c b/tools/widl/server.c index bb16c54ce33..3581fdc88b4 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -386,58 +386,69 @@ static void init_server(void) } -void write_server(ifref_list_t *ifaces) +static void write_server_stmts(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset) +{ + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type == STMT_LIBRARY) + write_server_stmts(stmt->u.lib->stmts, expr_eval_routines, proc_offset); + else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) + { + type_t *iface = stmt->u.type; + if (!need_stub(iface)) + continue; + + fprintf(server, "/*****************************************************************************\n"); + fprintf(server, " * %s interface\n", iface->name); + fprintf(server, " */\n"); + fprintf(server, "\n"); + + if (iface->funcs) + { + write_serverinterfacedecl(iface); + write_stubdescdecl(iface); + + write_function_stubs(iface, proc_offset); + + print_server("#if !defined(__RPC_WIN32__)\n"); + print_server("#error Invalid build platform for this stub.\n"); + print_server("#endif\n"); + + fprintf(server, "\n"); + write_stubdescriptor(iface, expr_eval_routines); + write_dispatchtable(iface); + } + } + } +} + +void write_server(const statement_list_t *stmts) { unsigned int proc_offset = 0; int expr_eval_routines; - ifref_t *iface; if (!do_server) return; - if (do_everything && !need_stub_files(ifaces)) + if (do_everything && !need_stub_files(stmts)) return; init_server(); if (!server) return; - write_formatstringsdecl(server, indent, ifaces, need_stub); + write_formatstringsdecl(server, indent, stmts, need_stub); expr_eval_routines = write_expr_eval_routines(server, server_token); if (expr_eval_routines) write_expr_eval_routine_list(server, server_token); write_user_quad_list(server); - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (!need_stub(iface->iface)) - continue; - - fprintf(server, "/*****************************************************************************\n"); - fprintf(server, " * %s interface\n", iface->iface->name); - fprintf(server, " */\n"); - fprintf(server, "\n"); - - if (iface->iface->funcs) - { - write_serverinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - - write_function_stubs(iface->iface, &proc_offset); - - print_server("#if !defined(__RPC_WIN32__)\n"); - print_server("#error Invalid build platform for this stub.\n"); - print_server("#endif\n"); - - fprintf(server, "\n"); - write_stubdescriptor(iface->iface, expr_eval_routines); - write_dispatchtable(iface->iface); - } - } + write_server_stmts(stmts, expr_eval_routines, &proc_offset); fprintf(server, "\n"); - write_procformatstring(server, ifaces, need_stub); - write_typeformatstring(server, ifaces, need_stub); + write_procformatstring(server, stmts, need_stub); + write_typeformatstring(server, stmts, need_stub); fclose(server); } diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index a2f8258cfd9..41134d803c7 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -43,7 +43,7 @@ static const func_t *current_func; static const type_t *current_structure; -static const ifref_t *current_iface; +static const type_t *current_iface; static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); struct expr_eval_routine @@ -370,13 +370,13 @@ static void write_formatdesc(FILE *f, int indent, const char *str) print_file(f, indent, "\n"); } -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred) +void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred) { print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n", - get_size_typeformatstring(ifaces, pred)); + get_size_typeformatstring(stmts, pred)); print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n", - get_size_procformatstring(ifaces, pred)); + get_size_procformatstring(stmts, pred)); fprintf(f, "\n"); write_formatdesc(f, indent, "TYPE"); @@ -477,33 +477,23 @@ static size_t write_procformatstring_type(FILE *file, int indent, return size; } -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) +static void write_procformatstring_stmts(FILE *file, int indent, const statement_list_t *stmts, type_pred_t pred) { - const ifref_t *iface; - int indent = 0; - const var_t *var; - - print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "0,\n"); - print_file(file, indent, "{\n"); - indent++; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) + const statement_t *stmt; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) { - if (!pred(iface->iface)) - continue; - - if (iface->iface->funcs) + if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP) { const func_t *func; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) + if (!pred(stmt->u.type)) + continue; + if (stmt->u.type->funcs) LIST_FOR_EACH_ENTRY( func, stmt->u.type->funcs, const func_t, entry ) { if (is_local(func->def->attrs)) continue; /* emit argument data */ if (func->args) { + const var_t *var; LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) write_procformatstring_type(file, indent, var->name, var->type, var->attrs, FALSE); } @@ -518,7 +508,23 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t write_procformatstring_type(file, indent, "return value", get_func_return_type(func), NULL, TRUE); } } + else if (stmt->type == STMT_LIBRARY) + write_procformatstring_stmts(file, indent, stmt->u.lib->stmts, pred); } +} + +void write_procformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred) +{ + int indent = 0; + + print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "0,\n"); + print_file(file, indent, "{\n"); + indent++; + + write_procformatstring_stmts(file, indent, stmts, pred); print_file(file, indent, "0x0\n"); indent--; @@ -2261,22 +2267,32 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty return retmask; } -static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) +static size_t process_tfs_stmts(FILE *file, const statement_list_t *stmts, + type_pred_t pred, unsigned int *typeformat_offset) { const var_t *var; - const ifref_t *iface; - unsigned int typeformat_offset = 2; + const statement_t *stmt; - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) { - if (!pred(iface->iface)) + const type_t *iface; + if (stmt->type == STMT_LIBRARY) + { + process_tfs_stmts(file, stmt->u.lib->stmts, pred, typeformat_offset); + continue; + } + else if (stmt->type != STMT_TYPE || stmt->u.type->type != RPC_FC_IP) continue; - if (iface->iface->funcs) + iface = stmt->u.type; + if (!pred(iface)) + continue; + + if (iface->funcs) { const func_t *func; current_iface = iface; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) + LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) { if (is_local(func->def->attrs)) continue; @@ -2287,7 +2303,7 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr update_tfsoff(get_func_return_type(func), write_typeformatstring_var( file, 2, NULL, get_func_return_type(func), - &v, &typeformat_offset), + &v, typeformat_offset), file); } @@ -2298,17 +2314,24 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr var->type, write_typeformatstring_var( file, 2, func, var->type, var, - &typeformat_offset), + typeformat_offset), file); } } } - return typeformat_offset + 1; + return *typeformat_offset + 1; +} + +static size_t process_tfs(FILE *file, const statement_list_t *stmts, type_pred_t pred) +{ + unsigned int typeformat_offset = 2; + + return process_tfs_stmts(file, stmts, pred, &typeformat_offset); } -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) +void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred) { int indent = 0; @@ -2321,7 +2344,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t print_file(file, indent, "NdrFcShort(0x0),\n"); set_all_tfswrite(TRUE); - process_tfs(file, ifaces, pred); + process_tfs(file, stmts, pred); print_file(file, indent, "0x0\n"); indent--; @@ -2984,29 +3007,39 @@ size_t get_size_procformatstring_func(const func_t *func) return size; } -size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred) +size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred) { - const ifref_t *iface; + const statement_t *stmt; size_t size = 1; const func_t *func; - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) { - if (!pred(iface->iface)) + const type_t *iface; + if (stmt->type == STMT_LIBRARY) + { + size += get_size_procformatstring(stmt->u.lib->stmts, pred) - 1; + continue; + } + else if (stmt->type != STMT_TYPE && stmt->u.type->type != RPC_FC_IP) continue; - if (iface->iface->funcs) - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) + iface = stmt->u.type; + if (!pred(iface)) + continue; + + if (iface->funcs) + LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) if (!is_local(func->def->attrs)) size += get_size_procformatstring_func( func ); } return size; } -size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred) +size_t get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred) { set_all_tfswrite(FALSE); - return process_tfs(NULL, ifaces, pred); + return process_tfs(NULL, stmts, pred); } void declare_stub_args( FILE *file, int indent, const func_t *func ) diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h index 7745454442e..a1013cb37f8 100644 --- a/tools/widl/typegen.h +++ b/tools/widl/typegen.h @@ -38,15 +38,15 @@ enum remoting_phase typedef int (*type_pred_t)(const type_t *); -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred); -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); +void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred); +void write_procformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred); +void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred); void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs); size_t get_size_procformatstring_func(const func_t *func); -size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred); -size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred); +size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred); +size_t get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred); void assign_stub_out_args( FILE *file, int indent, const func_t *func ); void declare_stub_args( FILE *file, int indent, const func_t *func ); int write_expr_eval_routines(FILE *file, const char *iface); diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index ac2815cc3f2..cd1c69b9ae9 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -232,6 +232,7 @@ unsigned short get_type_vt(type_t *t) case RPC_FC_CPSTRUCT: case RPC_FC_CVSTRUCT: case RPC_FC_BOGUS_STRUCT: + case RPC_FC_COCLASS: return VT_USERDEFINED; case 0: return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; @@ -241,20 +242,13 @@ unsigned short get_type_vt(type_t *t) return 0; } -void start_typelib(char *name, const attr_list_t *attrs) +void start_typelib(typelib_t *typelib_type) { in_typelib++; if (!do_typelib) return; - typelib = xmalloc(sizeof(*typelib)); - typelib->name = xstrdup(name); + typelib = typelib_type; typelib->filename = xstrdup(typelib_name); - typelib->attrs = attrs; - list_init( &typelib->entries ); - list_init( &typelib->importlibs ); - - if (is_attr(attrs, ATTR_POINTERDEFAULT)) - pointer_default = get_attrv(attrs, ATTR_POINTERDEFAULT); } void end_typelib(void) @@ -263,8 +257,6 @@ void end_typelib(void) if (!typelib) return; create_msft_typelib(typelib); - pointer_default = RPC_FC_UP; - return; } void add_typelib_entry(type_t *t) diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h index 9dce14ae072..486dbb49e3e 100644 --- a/tools/widl/typelib.h +++ b/tools/widl/typelib.h @@ -22,7 +22,7 @@ #define __WIDL_TYPELIB_H extern int in_typelib; -extern void start_typelib(char *name, const attr_list_t *attrs); +extern void start_typelib(typelib_t *typelib_type); extern void end_typelib(void); extern void add_typelib_entry(type_t *t); extern void add_importlib(const char *name); diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 13daf7e17fa..9b14de20fe4 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -279,13 +279,13 @@ static char *eat_space(char *s) return s; } -void write_dlldata(ifref_list_t *ifaces) +void write_dlldata(const statement_list_t *stmts) { struct list filenames = LIST_INIT(filenames); filename_node_t *node; FILE *dlldata; - if (!do_dlldata || !need_proxy_file(ifaces)) + if (!do_dlldata || !need_proxy_file(stmts)) return; dlldata = fopen(dlldata_name, "r"); diff --git a/tools/widl/widl.h b/tools/widl/widl.h index 924b67a3d88..f08a9ae326a 100644 --- a/tools/widl/widl.h +++ b/tools/widl/widl.h @@ -68,9 +68,9 @@ extern FILE* header; extern FILE* local_stubs; extern FILE* idfile; -extern void write_proxies(ifref_list_t *ifaces); -extern void write_client(ifref_list_t *ifaces); -extern void write_server(ifref_list_t *ifaces); -extern void write_dlldata(ifref_list_t *ifaces); +extern void write_proxies(const statement_list_t *stmts); +extern void write_client(const statement_list_t *stmts); +extern void write_server(const statement_list_t *stmts); +extern void write_dlldata(const statement_list_t *stmts); #endif diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 7b0f8487c95..10064b7f7c7 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -34,6 +34,7 @@ typedef GUID UUID; #define TRUE 1 #define FALSE 0 +#define RPC_FC_COCLASS 0xfd #define RPC_FC_FUNCTION 0xfe typedef struct _loc_info_t loc_info_t; @@ -51,6 +52,7 @@ typedef struct _importinfo_t importinfo_t; typedef struct _typelib_t typelib_t; typedef struct _user_type_t user_type_t; typedef struct _user_type_t context_handle_t; +typedef struct _statement_t statement_t; typedef struct list attr_list_t; typedef struct list str_list_t; @@ -62,6 +64,7 @@ typedef struct list ifref_list_t; typedef struct list array_dims_t; typedef struct list user_type_list_t; typedef struct list context_handle_list_t; +typedef struct list statement_list_t; enum attr_type { @@ -192,6 +195,20 @@ enum type_kind TKIND_MAX }; +enum statement_type +{ + STMT_LIBRARY, + STMT_INITDECL, + STMT_EXTERN, + STMT_TYPE, + STMT_TYPEREF, + STMT_MODULE, + STMT_TYPEDEF, + STMT_IMPORT, + STMT_IMPORTLIB, + STMT_CPPQUOTE +}; + struct _loc_info_t { const char *input_name; @@ -332,6 +349,7 @@ struct _typelib_t { const attr_list_t *attrs; struct list entries; struct list importlibs; + statement_list_t *stmts; }; struct _user_type_t { @@ -339,6 +357,19 @@ struct _user_type_t { const char *name; }; +struct _statement_t { + struct list entry; + enum statement_type type; + union + { + ifref_t iface; + type_t *type; + const char *str; + var_t *var; + typelib_t *lib; + } u; +}; + extern unsigned char pointer_default; extern user_type_list_t user_type_list; diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index accb648980c..01f9fd7b232 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -986,10 +986,11 @@ static int encode_type( case RPC_FC_ENUM16: add_enum_typeinfo(typelib, type); break; + case RPC_FC_COCLASS: + add_coclass_typeinfo(typelib, type); + break; case 0: - if (type->kind == TKIND_COCLASS) - add_coclass_typeinfo(typelib, type); - else if (type->kind == TKIND_DISPATCH) + if (type->kind == TKIND_DISPATCH) add_dispinterface_typeinfo(typelib, type); else error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n");