diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 005163ff1ba..1cb9ab981f5 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -134,6 +134,8 @@ static struct namespace global_namespace = { static struct namespace *current_namespace = &global_namespace; +static typelib_t *current_typelib; + %} %union { attr_t *attr; @@ -326,6 +328,7 @@ input: gbl_statements { fix_incomplete(); write_client($1); write_server($1); write_regscript($1); + write_typelib_regscript($1); write_dlldata($1); write_local_stubs($1); } @@ -424,21 +427,18 @@ import: import_start imp_statements aEOF { $$ = $1->name; ; importlib: tIMPORTLIB '(' aSTRING ')' - semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3); } + semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3, current_typelib); } ; libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } | tLIBRARY aKNOWNTYPE { $$ = $2; } ; library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1)); - if (!parse_only) start_typelib($$); + if (!parse_only && do_typelib) current_typelib = $$; } ; librarydef: library_start imp_statements '}' - semicolon_opt { $$ = $1; - $$->stmts = $2; - if (!parse_only) end_typelib(); - } + semicolon_opt { $$ = $1; $$->stmts = $2; } ; m_args: { $$ = NULL; } diff --git a/tools/widl/register.c b/tools/widl/register.c index 9a4f21930e5..210fb747158 100644 --- a/tools/widl/register.c +++ b/tools/widl/register.c @@ -34,6 +34,7 @@ #include "parser.h" #include "header.h" #include "typegen.h" +#include "typelib.h" static int indent; @@ -273,6 +274,24 @@ void write_regscript( const statement_list_t *stmts ) } } +void write_typelib_regscript( const statement_list_t *stmts ) +{ + const statement_t *stmt; + unsigned int count = 0; + + if (!do_typelib) return; + if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) + { + if (stmt->type != STMT_LIBRARY) continue; + if (count && !strendswith( typelib_name, ".res" )) + error( "Cannot store multiple typelibs into %s\n", typelib_name ); + else + create_msft_typelib( stmt->u.lib ); + count++; + } + if (count && strendswith( typelib_name, ".res" )) flush_output_resources( typelib_name ); +} + void output_typelib_regscript( const typelib_t *typelib ) { const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); @@ -281,6 +300,7 @@ void output_typelib_regscript( const typelib_t *typelib ) unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); unsigned int flags = 0; char id_part[12] = ""; + char *resname = typelib_name; expr_t *expr; if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */ @@ -299,7 +319,11 @@ void output_typelib_regscript( const typelib_t *typelib ) put_str( indent++, "{\n" ); expr = get_attrp( typelib->attrs, ATTR_ID ); if (expr) + { sprintf(id_part, "\\%d", expr->cval); + resname = xmalloc( strlen(typelib_name) + 20 ); + sprintf(resname, "%s\\%d", typelib_name, expr->cval); + } put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n", lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part ); put_str( indent, "FLAGS = s '%u'\n", flags ); @@ -320,5 +344,5 @@ void output_typelib_regscript( const typelib_t *typelib ) write_progids( typelib->stmts ); put_str( --indent, "}\n" ); - add_output_to_resources( "WINE_REGISTRY", typelib_name ); + add_output_to_resources( "WINE_REGISTRY", resname ); } diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index 2ebb50ed35b..30838394479 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -44,7 +44,6 @@ #include "typelib_struct.h" #include "typetree.h" -static typelib_t *typelib; /* List of oleauto types that should be recognized by name. * (most of) these seem to be intrinsic types in mktyplib. @@ -239,19 +238,6 @@ unsigned short get_type_vt(type_t *t) return 0; } -void start_typelib(typelib_t *typelib_type) -{ - if (!do_typelib) return; - typelib = typelib_type; -} - -void end_typelib(void) -{ - if (!typelib) return; - - create_msft_typelib(typelib); -} - static void tlb_read(int fd, void *buf, int count) { if(read(fd, buf, count) < count) @@ -376,7 +362,7 @@ static void read_importlib(importlib_t *importlib) close(fd); } -void add_importlib(const char *name) +void add_importlib(const char *name, typelib_t *typelib) { importlib_t *importlib; diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h index 18e6cdbcc56..7df7d290825 100644 --- a/tools/widl/typelib.h +++ b/tools/widl/typelib.h @@ -21,9 +21,7 @@ #ifndef __WIDL_TYPELIB_H #define __WIDL_TYPELIB_H -extern void start_typelib(typelib_t *typelib_type); -extern void end_typelib(void); -extern void add_importlib(const char *name); +extern void add_importlib(const char *name, typelib_t *typelib); /* Copied from wtypes.h. Not included directly because that would create a * circular dependency (after all, wtypes.h is generated by widl...) */ diff --git a/tools/widl/widl.h b/tools/widl/widl.h index 09e7871c848..7530f9ff429 100644 --- a/tools/widl/widl.h +++ b/tools/widl/widl.h @@ -89,6 +89,7 @@ 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_regscript(const statement_list_t *stmts); +extern void write_typelib_regscript(const statement_list_t *stmts); extern void output_typelib_regscript( const typelib_t *typelib ); extern void write_local_stubs(const statement_list_t *stmts); extern void write_dlldata(const statement_list_t *stmts); diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 5585a2f6f58..88a80d12ed7 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -2636,7 +2636,6 @@ static void save_all_changes(msft_typelib_t *typelib) sprintf( typelib_id, "#%d", expr->cval ); add_output_to_resources( "TYPELIB", typelib_id ); output_typelib_regscript( typelib->typelib ); - flush_output_resources( typelib_name ); } else flush_output_buffer( typelib_name ); }