/* * IDL Compiler * * Copyright 2004 Ove Kaaven * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include #include #include #include #include "widl.h" #include "utils.h" #include "parser.h" #include "header.h" #include "typelib.h" int in_typelib = 0; static FILE* typelib; /* Copied from wtypes.h. Not included directly because that would create a * circular dependency (after all, wtypes.h is generated by widl...) */ enum VARENUM { VT_EMPTY = 0, VT_NULL = 1, VT_I2 = 2, VT_I4 = 3, VT_R4 = 4, VT_R8 = 5, VT_CY = 6, VT_DATE = 7, VT_BSTR = 8, VT_DISPATCH = 9, VT_ERROR = 10, VT_BOOL = 11, VT_VARIANT = 12, VT_UNKNOWN = 13, VT_DECIMAL = 14, VT_I1 = 16, VT_UI1 = 17, VT_UI2 = 18, VT_UI4 = 19, VT_I8 = 20, VT_UI8 = 21, VT_INT = 22, VT_UINT = 23, VT_VOID = 24, VT_HRESULT = 25, VT_PTR = 26, VT_SAFEARRAY = 27, VT_CARRAY = 28, VT_USERDEFINED = 29, VT_LPSTR = 30, VT_LPWSTR = 31, VT_RECORD = 36, VT_FILETIME = 64, VT_BLOB = 65, VT_STREAM = 66, VT_STORAGE = 67, VT_STREAMED_OBJECT = 68, VT_STORED_OBJECT = 69, VT_BLOB_OBJECT = 70, VT_CF = 71, VT_CLSID = 72, VT_BSTR_BLOB = 0xfff, VT_VECTOR = 0x1000, VT_ARRAY = 0x2000, VT_BYREF = 0x4000, VT_RESERVED = 0x8000, VT_ILLEGAL = 0xffff, VT_ILLEGALMASKED = 0xfff, VT_TYPEMASK = 0xfff }; /* List of oleauto types that should be recognized by name. * (most of) these seem to be intrinsic types in mktyplib. */ static 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} }; #define NTYPES (sizeof(oatypes)/sizeof(oatypes[0])) #define KWP(p) ((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 char *kw) { struct oatype key, *kwp; key.kw = kw; #ifdef KW_BSEARCH kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); #else { 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; } 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; if (t->name) { vt = builtin_vt(t->name); if (vt) return vt; } switch (t->type) { case RPC_FC_BYTE: case RPC_FC_USMALL: return VT_UI1; case RPC_FC_CHAR: case RPC_FC_SMALL: return VT_I1; case RPC_FC_WCHAR: return VT_I2; /* mktyplib seems to parse wchar_t as short */ case RPC_FC_SHORT: return VT_I2; case RPC_FC_USHORT: return VT_UI2; case RPC_FC_LONG: if (t->ref && match(t->ref->name, "int")) return VT_INT; return VT_I4; case RPC_FC_ULONG: if (t->ref && match(t->ref->name, "int")) return VT_UINT; return VT_UI4; case RPC_FC_HYPER: if (t->sign < 0) return VT_UI8; if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8; return VT_I8; case RPC_FC_FLOAT: return VT_R4; case RPC_FC_DOUBLE: return VT_R8; case RPC_FC_RP: case RPC_FC_UP: case RPC_FC_OP: case RPC_FC_FP: /* it's a pointer... */ if (t->ref && t->ref->type == RPC_FC_IP) { /* it's to an interface, which one? */ if (match(t->ref->name, "IDispatch")) return VT_DISPATCH; if (match(t->ref->name, "IUnknown")) return VT_UNKNOWN; } /* FIXME: should we recurse and add a VT_BYREF? */ /* Or just return VT_PTR? */ error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); break; default: error("get_type_vt: unknown-type: %d\n", t->type); } return 0; } unsigned short get_var_vt(var_t *v) { unsigned short vt; if (v->tname) { vt = builtin_vt(v->tname); if (vt) return vt; } return get_type_vt(v->type); } void start_typelib(char *name, attr_t *attrs) { in_typelib++; if (!do_everything && !typelib_only) return; if(!(typelib = fopen(typelib_name, "wb"))) error("Could not open %s for output\n", typelib_name); } void end_typelib(void) { if (typelib) fclose(typelib); in_typelib--; } void add_interface(type_t *iface) { if (!typelib) return; /* FIXME: add interface and dependent types to typelib */ printf("add interface: %s\n", iface->name); } void add_coclass(class_t *cls) { ifref_t *lcur = cls->ifaces; ifref_t *cur; if (lcur) { while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur); } if (!typelib) return; /* install interfaces the coclass depends on */ cur = lcur; while (cur) { add_interface(cur->iface); cur = PREV_LINK(cur); } /* FIXME: add coclass to typelib */ printf("add coclass: %s\n", cls->name); } void add_module(type_t *module) { if (!typelib) return; /* FIXME: add module to typelib */ printf("add module: %s\n", module->name); }