widl: Support generating multiple typelibs into the same resource file.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-10-16 13:47:54 +02:00
parent 3adddfecc3
commit c34e245137
6 changed files with 34 additions and 26 deletions

View File

@ -134,6 +134,8 @@ static struct namespace global_namespace = {
static struct namespace *current_namespace = &global_namespace; static struct namespace *current_namespace = &global_namespace;
static typelib_t *current_typelib;
%} %}
%union { %union {
attr_t *attr; attr_t *attr;
@ -326,6 +328,7 @@ input: gbl_statements { fix_incomplete();
write_client($1); write_client($1);
write_server($1); write_server($1);
write_regscript($1); write_regscript($1);
write_typelib_regscript($1);
write_dlldata($1); write_dlldata($1);
write_local_stubs($1); write_local_stubs($1);
} }
@ -424,21 +427,18 @@ import: import_start imp_statements aEOF { $$ = $1->name;
; ;
importlib: tIMPORTLIB '(' aSTRING ')' 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; } libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
| tLIBRARY aKNOWNTYPE { $$ = $2; } | tLIBRARY aKNOWNTYPE { $$ = $2; }
; ;
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1)); 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 '}' librarydef: library_start imp_statements '}'
semicolon_opt { $$ = $1; semicolon_opt { $$ = $1; $$->stmts = $2; }
$$->stmts = $2;
if (!parse_only) end_typelib();
}
; ;
m_args: { $$ = NULL; } m_args: { $$ = NULL; }

View File

@ -34,6 +34,7 @@
#include "parser.h" #include "parser.h"
#include "header.h" #include "header.h"
#include "typegen.h" #include "typegen.h"
#include "typelib.h"
static int indent; 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 ) void output_typelib_regscript( const typelib_t *typelib )
{ {
const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); 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 version = get_attrv( typelib->attrs, ATTR_VERSION );
unsigned int flags = 0; unsigned int flags = 0;
char id_part[12] = ""; char id_part[12] = "";
char *resname = typelib_name;
expr_t *expr; expr_t *expr;
if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */ 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" ); put_str( indent++, "{\n" );
expr = get_attrp( typelib->attrs, ATTR_ID ); expr = get_attrp( typelib->attrs, ATTR_ID );
if (expr) if (expr)
{
sprintf(id_part, "\\%d", expr->cval); 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", put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part ); lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part );
put_str( indent, "FLAGS = s '%u'\n", flags ); put_str( indent, "FLAGS = s '%u'\n", flags );
@ -320,5 +344,5 @@ void output_typelib_regscript( const typelib_t *typelib )
write_progids( typelib->stmts ); write_progids( typelib->stmts );
put_str( --indent, "}\n" ); put_str( --indent, "}\n" );
add_output_to_resources( "WINE_REGISTRY", typelib_name ); add_output_to_resources( "WINE_REGISTRY", resname );
} }

View File

@ -44,7 +44,6 @@
#include "typelib_struct.h" #include "typelib_struct.h"
#include "typetree.h" #include "typetree.h"
static typelib_t *typelib;
/* List of oleauto types that should be recognized by name. /* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib. * (most of) these seem to be intrinsic types in mktyplib.
@ -239,19 +238,6 @@ unsigned short get_type_vt(type_t *t)
return 0; 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) static void tlb_read(int fd, void *buf, int count)
{ {
if(read(fd, buf, count) < count) if(read(fd, buf, count) < count)
@ -376,7 +362,7 @@ static void read_importlib(importlib_t *importlib)
close(fd); close(fd);
} }
void add_importlib(const char *name) void add_importlib(const char *name, typelib_t *typelib)
{ {
importlib_t *importlib; importlib_t *importlib;

View File

@ -21,9 +21,7 @@
#ifndef __WIDL_TYPELIB_H #ifndef __WIDL_TYPELIB_H
#define __WIDL_TYPELIB_H #define __WIDL_TYPELIB_H
extern void start_typelib(typelib_t *typelib_type); extern void add_importlib(const char *name, typelib_t *typelib);
extern void end_typelib(void);
extern void add_importlib(const char *name);
/* Copied from wtypes.h. Not included directly because that would create a /* Copied from wtypes.h. Not included directly because that would create a
* circular dependency (after all, wtypes.h is generated by widl...) */ * circular dependency (after all, wtypes.h is generated by widl...) */

View File

@ -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_client(const statement_list_t *stmts);
extern void write_server(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_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 output_typelib_regscript( const typelib_t *typelib );
extern void write_local_stubs(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 write_dlldata(const statement_list_t *stmts);

View File

@ -2636,7 +2636,6 @@ static void save_all_changes(msft_typelib_t *typelib)
sprintf( typelib_id, "#%d", expr->cval ); sprintf( typelib_id, "#%d", expr->cval );
add_output_to_resources( "TYPELIB", typelib_id ); add_output_to_resources( "TYPELIB", typelib_id );
output_typelib_regscript( typelib->typelib ); output_typelib_regscript( typelib->typelib );
flush_output_resources( typelib_name );
} }
else flush_output_buffer( typelib_name ); else flush_output_buffer( typelib_name );
} }