reactos/sdk/tools/widl/typelib.c

411 lines
9.9 KiB
C
Raw Normal View History

/*
* IDL Compiler
*
* Copyright 2004 Ove Kaaven
* Copyright 2006 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include "wine/wpp.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include <ctype.h>
#ifdef __REACTOS__
#include <typedefs.h>
#else
#include "windef.h"
#include "winbase.h"
#endif
#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "header.h"
#include "typelib.h"
#include "widltypes.h"
#include "typelib_struct.h"
#include "typetree.h"
#ifdef __REACTOS__
static typelib_t *typelib;
#endif
/* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib.
* This table MUST be alphabetically sorted on the kw field.
*/
static const struct oatype {
const char *kw;
unsigned short vt;
} oatypes[] = {
{"BSTR", VT_BSTR},
{"CURRENCY", VT_CY},
{"DATE", VT_DATE},
{"DECIMAL", VT_DECIMAL},
{"HRESULT", VT_HRESULT},
{"LPSTR", VT_LPSTR},
{"LPWSTR", VT_LPWSTR},
{"SCODE", VT_ERROR},
{"VARIANT", VT_VARIANT},
{"VARIANT_BOOL", VT_BOOL}
};
#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0]))
#define KWP(p) ((const struct oatype *)(p))
static int kw_cmp_func(const void *s1, const void *s2)
{
return strcmp(KWP(s1)->kw, KWP(s2)->kw);
}
static unsigned short builtin_vt(const type_t *t)
{
const char *kw = t->name;
struct oatype key;
const struct oatype *kwp;
key.kw = kw;
#ifdef KW_BSEARCH
kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func);
#else
{
unsigned int i;
for (kwp=NULL, i=0; i < NTYPES; i++)
if (!kw_cmp_func(&key, &oatypes[i])) {
kwp = &oatypes[i];
break;
}
}
#endif
if (kwp) {
return kwp->vt;
}
if (is_string_type (t->attrs, t))
{
const type_t *elem_type;
if (is_array(t))
elem_type = type_array_get_element(t);
else
elem_type = type_pointer_get_ref(t);
if (type_get_type(elem_type) == TYPE_BASIC)
{
switch (type_basic_get_type(elem_type))
{
case TYPE_BASIC_CHAR: return VT_LPSTR;
case TYPE_BASIC_WCHAR: return VT_LPWSTR;
default: break;
}
}
}
return 0;
}
static int match(const char*n, const char*m)
{
if (!n) return 0;
return !strcmp(n, m);
}
unsigned short get_type_vt(type_t *t)
{
unsigned short vt;
chat("get_type_vt: %p type->name %s\n", t, t->name);
if (t->name) {
vt = builtin_vt(t);
if (vt) return vt;
}
if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
return VT_USERDEFINED;
switch (type_get_type(t)) {
case TYPE_BASIC:
switch (type_basic_get_type(t)) {
case TYPE_BASIC_BYTE:
return VT_UI1;
case TYPE_BASIC_CHAR:
case TYPE_BASIC_INT8:
if (type_basic_get_sign(t) > 0)
return VT_UI1;
else
return VT_I1;
case TYPE_BASIC_WCHAR:
return VT_I2; /* mktyplib seems to parse wchar_t as short */
case TYPE_BASIC_INT16:
if (type_basic_get_sign(t) > 0)
return VT_UI2;
else
return VT_I2;
case TYPE_BASIC_INT:
if (type_basic_get_sign(t) > 0)
return VT_UINT;
else
return VT_INT;
case TYPE_BASIC_INT32:
case TYPE_BASIC_LONG:
case TYPE_BASIC_ERROR_STATUS_T:
if (type_basic_get_sign(t) > 0)
return VT_UI4;
else
return VT_I4;
case TYPE_BASIC_INT64:
case TYPE_BASIC_HYPER:
if (type_basic_get_sign(t) > 0)
return VT_UI8;
else
return VT_I8;
case TYPE_BASIC_INT3264:
if (pointer_size == 8)
{
if (type_basic_get_sign(t) > 0)
return VT_UI8;
else
return VT_I8;
}
else
{
if (type_basic_get_sign(t) > 0)
return VT_UI4;
else
return VT_I4;
}
case TYPE_BASIC_FLOAT:
return VT_R4;
case TYPE_BASIC_DOUBLE:
return VT_R8;
case TYPE_BASIC_HANDLE:
error("handles can't be used in typelibs\n");
}
break;
case TYPE_POINTER:
return VT_PTR;
case TYPE_ARRAY:
if (type_array_is_decl_as_ptr(t))
{
if (match(type_array_get_element(t)->name, "SAFEARRAY"))
return VT_SAFEARRAY;
return VT_PTR;
}
else
return VT_CARRAY;
case TYPE_INTERFACE:
if(match(t->name, "IUnknown"))
return VT_UNKNOWN;
if(match(t->name, "IDispatch"))
return VT_DISPATCH;
return VT_USERDEFINED;
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_COCLASS:
case TYPE_MODULE:
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
return VT_USERDEFINED;
case TYPE_VOID:
return VT_VOID;
case TYPE_ALIAS:
/* aliases should be filtered out by the type_get_type call above */
assert(0);
break;
case TYPE_FUNCTION:
error("get_type_vt: functions not supported\n");
break;
case TYPE_BITFIELD:
error("get_type_vt: bitfields not supported\n");
break;
}
return 0;
}
#ifdef __REACTOS__
Sync to wine-0.9.61: - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Stop looping in check_remoting_args when a context_handle or wire_marshal type is found as they are in effect fundamental types. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Check that fields in structures and unions referenced by non-local functions can be marshalled and that their attributes are consistent. -Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: The implicit_handle attribute is allowed with a handle explicitly specified in the function parameters. In that case, that handle is used instead of the implicit handle. Fix the check for the explicit_handle attribute being specified without a handle being specified in the function parameters, even though issuing an error is wrong. (Thanks to Marcus Meissner & Coverity for spotting that the check didn't do what it was supposed to do.) - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Automatically add "handle_t IDL_handle" parameter to functions with no explicit handle specified whose containing interface has the explicit_handle attribute. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Issue an error instead of crashing for dividing by zero in a constant expression. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for "->" and "." operators in expressions. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for arrays in expressions. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for '%' operator in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Fix operator precedence in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Require a constant expression for case statements. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Add support for comparison, exclusive or, logical not and positive operators in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Remove EXPR_MEMBERPTR and implement it using EXPR_PPTR and EXPR_MEMBER instead. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Don't free input_name in pop_import as we keep pointers to it in the var_t type now. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Pass the actual type into check_remoting_fields and check_field_common instead of the type name. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Check that expressions resolve so that expressions in generated code will compile. Also check that expressions return the correct type for the attribute. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Move expression functions to a new file, expr.c. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Use expr_resolve_type to get the type of the identifier in write_conf_or_var_desc. Remove the conversion of pointer types into base types as this was only needed due to lack of proper type resolving. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Remove duplicated code in the form of the write_struct_expr function by enhancing write_expr to allow toplevel identifiers to be prefixed by a string, if specified. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Implement lcid property on library declarations. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Construct the pointer chain while parsing pointers, rather than storing a ptr_level. This method is more flexible and somewhat simpler. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Allow NULL to be used in expressions. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Create a list of statements in the whole IDL file, instead of just a list of interfaces. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Add typedef statements to the statement lists. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Consolidate most of the inner loop of reg_typedefs into set_type. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Rename pident to declarator and parse the array declarations as part of declarators. This allows arrays to be used in typedefs and const statements. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Make the rules for parsing fields in structures, encapsulated unions and non-encapsulated unions more strict. Move the rules in fields that handle empty union cases into separate union rules so that they can't erroneously be accepted for structures or other types of unions. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Add support for declaring multiple fields of a structure in one statement. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Add support for string literals and wide-string literals in expressions. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Create a statement object for import statements. Move the writing of include directives into the generated header into header.c. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Move the func_declarator rule entirely into direct_declarator. - Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008 widl: Add typedefs to typelibs which have the public or uuid attributes, not any other attribute. - Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008 widl: Support hex digits that use an uppercase 0X prefix. - Rob Shearman <rob@codeweavers.com> Sun, 27 Apr 2008 widl: Accept integer constant suffixes in the lexer. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Keep const attributes applied to pointers when writing out the type. Use an attribute to store the const qualifier for the pointer and type. Allow multiple type-qualifiers to be applied to a type by adding a declaration-specifier rule that encompasses type-qualifiers and types. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Add support for "inline" on function definitions. Fix applying calling convention to function type. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Make constdef and externdef take a declarator instead of an ident so that functions and arrays can be defined using the statements. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Allow pointer attributes to be applied to function pointers. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: callback, code, comm_status and in_line are attribute names, not keywords. - Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008 widl: Prepare for supporting storage classes in declaration statements. Return a decl_spec_t structure from decl_spec rules so that the storage class and type qualifiers can both be returned. - Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008 widl: Add the parsing of storage classes into declaration-specifiers. Support the static and register keywords. This consolidates externdef and constdef rules into one declaration rule. - Rob Shearman <rob@codeweavers.com> Thu, 1 May 2008 widl: Consolidate writing of COM and dispatch interfaces into one function to remove duplicated code. Split up the writing into start and end to eventually support the style MIDL uses where it writes declared types, etc. between the start and end of the interface. Make internal header functions take the file pointer to print to. Don't write interface IDs for non-object interfaces and always write handle declarations even if the interface has no methods, like MIDL does. - Gerald Pfeifer <gerald@pfeifer.com> Fri, 2 May 2008 widl: Fix syntax to also work with older versions of bison. svn path=/trunk/; revision=37313
2008-11-12 19:26:25 +00:00
void start_typelib(typelib_t *typelib_type)
{
if (!do_typelib) return;
Sync to wine-0.9.61: - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Stop looping in check_remoting_args when a context_handle or wire_marshal type is found as they are in effect fundamental types. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Check that fields in structures and unions referenced by non-local functions can be marshalled and that their attributes are consistent. -Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: The implicit_handle attribute is allowed with a handle explicitly specified in the function parameters. In that case, that handle is used instead of the implicit handle. Fix the check for the explicit_handle attribute being specified without a handle being specified in the function parameters, even though issuing an error is wrong. (Thanks to Marcus Meissner & Coverity for spotting that the check didn't do what it was supposed to do.) - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Automatically add "handle_t IDL_handle" parameter to functions with no explicit handle specified whose containing interface has the explicit_handle attribute. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Issue an error instead of crashing for dividing by zero in a constant expression. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for "->" and "." operators in expressions. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for arrays in expressions. - Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008 widl: Add support for '%' operator in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Fix operator precedence in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Require a constant expression for case statements. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Add support for comparison, exclusive or, logical not and positive operators in expressions. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Remove EXPR_MEMBERPTR and implement it using EXPR_PPTR and EXPR_MEMBER instead. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Don't free input_name in pop_import as we keep pointers to it in the var_t type now. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Pass the actual type into check_remoting_fields and check_field_common instead of the type name. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Check that expressions resolve so that expressions in generated code will compile. Also check that expressions return the correct type for the attribute. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Move expression functions to a new file, expr.c. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Use expr_resolve_type to get the type of the identifier in write_conf_or_var_desc. Remove the conversion of pointer types into base types as this was only needed due to lack of proper type resolving. - Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008 widl: Remove duplicated code in the form of the write_struct_expr function by enhancing write_expr to allow toplevel identifiers to be prefixed by a string, if specified. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Implement lcid property on library declarations. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Construct the pointer chain while parsing pointers, rather than storing a ptr_level. This method is more flexible and somewhat simpler. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Allow NULL to be used in expressions. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Create a list of statements in the whole IDL file, instead of just a list of interfaces. - Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008 widl: Add typedef statements to the statement lists. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Consolidate most of the inner loop of reg_typedefs into set_type. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Rename pident to declarator and parse the array declarations as part of declarators. This allows arrays to be used in typedefs and const statements. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Make the rules for parsing fields in structures, encapsulated unions and non-encapsulated unions more strict. Move the rules in fields that handle empty union cases into separate union rules so that they can't erroneously be accepted for structures or other types of unions. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Add support for declaring multiple fields of a structure in one statement. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Add support for string literals and wide-string literals in expressions. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Create a statement object for import statements. Move the writing of include directives into the generated header into header.c. - Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008 widl: Move the func_declarator rule entirely into direct_declarator. - Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008 widl: Add typedefs to typelibs which have the public or uuid attributes, not any other attribute. - Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008 widl: Support hex digits that use an uppercase 0X prefix. - Rob Shearman <rob@codeweavers.com> Sun, 27 Apr 2008 widl: Accept integer constant suffixes in the lexer. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Keep const attributes applied to pointers when writing out the type. Use an attribute to store the const qualifier for the pointer and type. Allow multiple type-qualifiers to be applied to a type by adding a declaration-specifier rule that encompasses type-qualifiers and types. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Add support for "inline" on function definitions. Fix applying calling convention to function type. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Make constdef and externdef take a declarator instead of an ident so that functions and arrays can be defined using the statements. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: Allow pointer attributes to be applied to function pointers. - Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008 widl: callback, code, comm_status and in_line are attribute names, not keywords. - Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008 widl: Prepare for supporting storage classes in declaration statements. Return a decl_spec_t structure from decl_spec rules so that the storage class and type qualifiers can both be returned. - Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008 widl: Add the parsing of storage classes into declaration-specifiers. Support the static and register keywords. This consolidates externdef and constdef rules into one declaration rule. - Rob Shearman <rob@codeweavers.com> Thu, 1 May 2008 widl: Consolidate writing of COM and dispatch interfaces into one function to remove duplicated code. Split up the writing into start and end to eventually support the style MIDL uses where it writes declared types, etc. between the start and end of the interface. Make internal header functions take the file pointer to print to. Don't write interface IDs for non-object interfaces and always write handle declarations even if the interface has no methods, like MIDL does. - Gerald Pfeifer <gerald@pfeifer.com> Fri, 2 May 2008 widl: Fix syntax to also work with older versions of bison. svn path=/trunk/; revision=37313
2008-11-12 19:26:25 +00:00
typelib = typelib_type;
}
void end_typelib(void)
{
if (!typelib) return;
create_msft_typelib(typelib);
}
#endif
static void tlb_read(int fd, void *buf, int count)
{
if(read(fd, buf, count) < count)
error("error while reading importlib.\n");
}
static void tlb_lseek(int fd, off_t offset)
{
if(lseek(fd, offset, SEEK_SET) == -1)
error("lseek failed\n");
}
static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid)
{
tlb_lseek(fd, segdir->pGuidTab.offset+offset);
tlb_read(fd, guid, sizeof(GUID));
}
static void read_msft_importlib(importlib_t *importlib, int fd)
{
MSFT_Header header;
MSFT_SegDir segdir;
int *typeinfo_offs;
int i;
importlib->allocated = 0;
tlb_lseek(fd, 0);
tlb_read(fd, &header, sizeof(header));
importlib->version = header.version;
typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT));
tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT));
tlb_read(fd, &segdir, sizeof(segdir));
msft_read_guid(fd, &segdir, header.posguid, &importlib->guid);
importlib->ntypeinfos = header.nrtypeinfos;
importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t));
for(i=0; i < importlib->ntypeinfos; i++) {
MSFT_TypeInfoBase base;
MSFT_NameIntro nameintro;
int len;
tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir)
+ typeinfo_offs[i]);
tlb_read(fd, &base, sizeof(base));
importlib->importinfos[i].importlib = importlib;
importlib->importinfos[i].flags = (base.typekind&0xf)<<24;
importlib->importinfos[i].offset = -1;
importlib->importinfos[i].id = i;
if(base.posguid != -1) {
importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid);
}
else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid));
tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset);
tlb_read(fd, &nameintro, sizeof(nameintro));
len = nameintro.namelen & 0xff;
importlib->importinfos[i].name = xmalloc(len+1);
tlb_read(fd, importlib->importinfos[i].name, len);
importlib->importinfos[i].name[len] = 0;
}
free(typeinfo_offs);
}
static int open_typelib(const char *name)
{
char *file_name;
int fd;
file_name = wpp_find_include(name, NULL);
if(!file_name)
return open(name, O_RDONLY | O_BINARY );
fd = open(file_name, O_RDONLY | O_BINARY );
free(file_name);
return fd;
}
static void read_importlib(importlib_t *importlib)
{
int fd;
INT magic;
fd = open_typelib(importlib->name);
/* widl extension: if importlib name has no .tlb extension, try using .tlb */
if(fd < 0) {
const char *p = strrchr(importlib->name, '.');
size_t len = p ? p - importlib->name : strlen(importlib->name);
if(strcmp(importlib->name + len, ".tlb")) {
char *tlb_name = xmalloc(len + 5);
memcpy(tlb_name, importlib->name, len);
strcpy(tlb_name + len, ".tlb");
fd = open_typelib(tlb_name);
free(tlb_name);
}
}
if(fd < 0)
error("Could not find importlib %s.\n", importlib->name);
tlb_read(fd, &magic, sizeof(magic));
switch(magic) {
case MSFT_MAGIC:
read_msft_importlib(importlib, fd);
break;
default:
error("Wrong or unsupported typelib magic %x\n", magic);
};
close(fd);
}
#ifdef __REACTOS__
void add_importlib(const char *name)
#else
void add_importlib(const char *name, typelib_t *typelib)
#endif
{
importlib_t *importlib;
if(!typelib) return;
LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry )
if(!strcmp(name, importlib->name))
return;
chat("add_importlib: %s\n", name);
importlib = xmalloc(sizeof(*importlib));
memset( importlib, 0, sizeof(*importlib) );
importlib->name = xstrdup(name);
read_importlib(importlib);
list_add_head( &typelib->importlibs, &importlib->entry );
}