widl: Write the typelib based on the statement list generated in the typelib_t object instead of using hooks in the parser code.

This commit is contained in:
Rob Shearman 2008-12-29 12:06:06 +00:00 committed by Alexandre Julliard
parent 1a71479fbd
commit 5223d04a7c
5 changed files with 51 additions and 65 deletions

View File

@ -369,27 +369,23 @@ gbl_statements: { $$ = NULL; }
if (!parse_only && do_header) write_coclass_forward($2);
}
| 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 { $$ = append_statement($1, make_statement_module($2));
add_typelib_entry($2);
}
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
| gbl_statements statement { $$ = append_statement($1, $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 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 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 { $$ = append_statement($1, make_statement_module($2)); if (!parse_only) add_typelib_entry($2); }
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($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)); }
@ -644,10 +640,7 @@ enum: ident '=' expr_int_const { $$ = reg_const($1);
}
;
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, $4);
if(in_typelib)
add_typelib_entry($$);
}
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, $4); }
;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
@ -1048,10 +1041,7 @@ pointer_type:
| tPTR { $$ = RPC_FC_FP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4);
if(in_typelib)
add_typelib_entry($$);
}
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4); }
;
type: tVOID { $$ = find_type_or_error("void", 0); }
@ -1783,7 +1773,6 @@ static typelib_t *make_library(const char *name, const attr_list_t *attrs)
typelib->name = xstrdup(name);
typelib->filename = NULL;
typelib->attrs = attrs;
list_init( &typelib->entries );
list_init( &typelib->importlibs );
return typelib;
}
@ -2746,8 +2735,6 @@ static statement_t *process_typedefs(declarator_list_t *decls)
if (! parse_only && do_header)
write_typedef(type);
if (in_typelib && is_attr(type->attrs, ATTR_PUBLIC))
add_typelib_entry(type);
type_list = &(*type_list)->next;
free(decl);

View File

@ -46,8 +46,6 @@
#include "widltypes.h"
#include "typelib_struct.h"
int in_typelib = 0;
static typelib_t *typelib;
type_t *duptype(type_t *t, int dupname)
@ -246,7 +244,6 @@ unsigned short get_type_vt(type_t *t)
void start_typelib(typelib_t *typelib_type)
{
in_typelib++;
if (!do_typelib) return;
typelib = typelib_type;
@ -255,23 +252,11 @@ void start_typelib(typelib_t *typelib_type)
void end_typelib(void)
{
in_typelib--;
if (!typelib) return;
create_msft_typelib(typelib);
}
void add_typelib_entry(type_t *t)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add kind %i: %s\n", t->kind, t->name);
entry = xmalloc(sizeof(*entry));
entry->type = t;
list_add_tail( &typelib->entries, &entry->entry );
}
static void tlb_read(int fd, void *buf, int count)
{
if(read(fd, buf, count) < count)

View File

@ -21,10 +21,8 @@
#ifndef __WIDL_TYPELIB_H
#define __WIDL_TYPELIB_H
extern int in_typelib;
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);
/* Copied from wtypes.h. Not included directly because that would create a

View File

@ -387,7 +387,6 @@ struct _typelib_t {
char *name;
char *filename;
const attr_list_t *attrs;
struct list entries;
struct list importlibs;
statement_list_t *stmts;
};

View File

@ -2191,38 +2191,54 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
msft_typeinfo->typeinfo->size = idx;
}
static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
{
switch(entry->type->kind) {
case TKIND_INTERFACE:
case TKIND_DISPATCH:
add_interface_typeinfo(typelib, entry->type);
switch(stmt->type) {
case STMT_LIBRARY:
case STMT_IMPORT:
case STMT_CPPQUOTE:
case STMT_DECLARATION:
/* not included in typelib */
break;
case TKIND_RECORD:
add_structure_typeinfo(typelib, entry->type);
case STMT_IMPORTLIB:
/* not processed here */
break;
case TKIND_ENUM:
add_enum_typeinfo(typelib, entry->type);
case STMT_TYPEDEF:
{
const type_list_t *type_entry = stmt->u.type_list;
for (; type_entry; type_entry = type_entry->next)
if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
add_typedef_typeinfo(typelib, type_entry->type);
break;
case TKIND_ALIAS:
add_typedef_typeinfo(typelib, entry->type);
}
case STMT_MODULE:
add_module_typeinfo(typelib, stmt->u.type);
break;
case TKIND_COCLASS:
add_coclass_typeinfo(typelib, entry->type);
break;
case TKIND_MODULE:
add_module_typeinfo(typelib, entry->type);
break;
default:
error("add_entry: unhandled type %d\n", entry->type->kind);
case STMT_TYPE:
case STMT_TYPEREF:
{
type_t *type = stmt->u.type;
switch (type->kind) {
case TKIND_INTERFACE:
case TKIND_DISPATCH:
add_interface_typeinfo(typelib, type);
break;
case TKIND_RECORD:
add_structure_typeinfo(typelib, type);
break;
case TKIND_ENUM:
add_enum_typeinfo(typelib, type);
break;
case TKIND_COCLASS:
add_coclass_typeinfo(typelib, type);
break;
default:
error("add_entry: unhandled type %d\n", type->kind);
break;
}
break;
}
}
}
static void set_name(msft_typelib_t *typelib)
@ -2497,7 +2513,7 @@ int create_msft_typelib(typelib_t *typelib)
{
msft_typelib_t *msft;
int failed = 0;
typelib_entry_t *entry;
const statement_t *stmt;
time_t cur_time;
char *time_override;
unsigned int version = 5 << 24 | 1 << 16 | 164; /* 5.01.0164 */
@ -2550,8 +2566,9 @@ int create_msft_typelib(typelib_t *typelib)
set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);
set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
LIST_FOR_EACH_ENTRY( entry, &typelib->entries, typelib_entry_t, entry )
add_entry(msft, entry);
if (typelib->stmts)
LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry )
add_entry(msft, stmt);
save_all_changes(msft);
free(msft);