Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentypelib.c
Go to the documentation of this file.
00001 /* 00002 * IDL Compiler 00003 * 00004 * Copyright 2004 Ove Kaaven 00005 * Copyright 2006 Jacek Caban for CodeWeavers 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "config.h" 00023 #include "wine/port.h" 00024 #include "wine/wpp.h" 00025 00026 #include <stdio.h> 00027 #include <stdlib.h> 00028 #include <stdarg.h> 00029 #ifdef HAVE_UNISTD_H 00030 # include <unistd.h> 00031 #endif 00032 #include <string.h> 00033 #include <ctype.h> 00034 00035 #define NONAMELESSUNION 00036 #define NONAMELESSSTRUCT 00037 00038 #include <typedefs.h> 00039 #include "widl.h" 00040 #include "utils.h" 00041 #include "parser.h" 00042 #include "header.h" 00043 #include "typelib.h" 00044 #include "widltypes.h" 00045 #include "typelib_struct.h" 00046 #include "typetree.h" 00047 00048 static typelib_t *typelib; 00049 00050 int is_ptr(const type_t *t) 00051 { 00052 return type_get_type(t) == TYPE_POINTER; 00053 } 00054 00055 int is_array(const type_t *t) 00056 { 00057 return type_get_type(t) == TYPE_ARRAY; 00058 } 00059 00060 /* List of oleauto types that should be recognized by name. 00061 * (most of) these seem to be intrinsic types in mktyplib. 00062 * This table MUST be alphabetically sorted on the kw field. 00063 */ 00064 static const struct oatype { 00065 const char *kw; 00066 unsigned short vt; 00067 } oatypes[] = { 00068 {"BSTR", VT_BSTR}, 00069 {"CURRENCY", VT_CY}, 00070 {"DATE", VT_DATE}, 00071 {"DECIMAL", VT_DECIMAL}, 00072 {"HRESULT", VT_HRESULT}, 00073 {"LPSTR", VT_LPSTR}, 00074 {"LPWSTR", VT_LPWSTR}, 00075 {"SCODE", VT_ERROR}, 00076 {"VARIANT", VT_VARIANT}, 00077 {"VARIANT_BOOL", VT_BOOL} 00078 }; 00079 #define NTYPES (sizeof(oatypes)/sizeof(oatypes[0])) 00080 #define KWP(p) ((const struct oatype *)(p)) 00081 00082 static int kw_cmp_func(const void *s1, const void *s2) 00083 { 00084 return strcmp(KWP(s1)->kw, KWP(s2)->kw); 00085 } 00086 00087 static unsigned short builtin_vt(const type_t *t) 00088 { 00089 const char *kw = t->name; 00090 struct oatype key; 00091 const struct oatype *kwp; 00092 key.kw = kw; 00093 #ifdef KW_BSEARCH 00094 kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); 00095 #else 00096 { 00097 unsigned int i; 00098 for (kwp=NULL, i=0; i < NTYPES; i++) 00099 if (!kw_cmp_func(&key, &oatypes[i])) { 00100 kwp = &oatypes[i]; 00101 break; 00102 } 00103 } 00104 #endif 00105 if (kwp) { 00106 return kwp->vt; 00107 } 00108 if (is_string_type (t->attrs, t)) 00109 { 00110 const type_t *elem_type; 00111 if (is_array(t)) 00112 elem_type = type_array_get_element(t); 00113 else 00114 elem_type = type_pointer_get_ref(t); 00115 if (type_get_type(elem_type) == TYPE_BASIC) 00116 { 00117 switch (type_basic_get_type(elem_type)) 00118 { 00119 case TYPE_BASIC_CHAR: return VT_LPSTR; 00120 case TYPE_BASIC_WCHAR: return VT_LPWSTR; 00121 default: break; 00122 } 00123 } 00124 } 00125 return 0; 00126 } 00127 00128 static int match(const char*n, const char*m) 00129 { 00130 if (!n) return 0; 00131 return !strcmp(n, m); 00132 } 00133 00134 unsigned short get_type_vt(type_t *t) 00135 { 00136 unsigned short vt; 00137 00138 chat("get_type_vt: %p type->name %s\n", t, t->name); 00139 if (t->name) { 00140 vt = builtin_vt(t); 00141 if (vt) return vt; 00142 } 00143 00144 if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC)) 00145 return VT_USERDEFINED; 00146 00147 switch (type_get_type(t)) { 00148 case TYPE_BASIC: 00149 switch (type_basic_get_type(t)) { 00150 case TYPE_BASIC_BYTE: 00151 return VT_UI1; 00152 case TYPE_BASIC_CHAR: 00153 case TYPE_BASIC_INT8: 00154 if (type_basic_get_sign(t) > 0) 00155 return VT_UI1; 00156 else 00157 return VT_I1; 00158 case TYPE_BASIC_WCHAR: 00159 return VT_I2; /* mktyplib seems to parse wchar_t as short */ 00160 case TYPE_BASIC_INT16: 00161 if (type_basic_get_sign(t) > 0) 00162 return VT_UI2; 00163 else 00164 return VT_I2; 00165 case TYPE_BASIC_INT: 00166 if (type_basic_get_sign(t) > 0) 00167 return VT_UINT; 00168 else 00169 return VT_INT; 00170 case TYPE_BASIC_INT32: 00171 case TYPE_BASIC_ERROR_STATUS_T: 00172 if (type_basic_get_sign(t) > 0) 00173 return VT_UI4; 00174 else 00175 return VT_I4; 00176 case TYPE_BASIC_INT64: 00177 case TYPE_BASIC_HYPER: 00178 if (type_basic_get_sign(t) > 0) 00179 return VT_UI8; 00180 else 00181 return VT_I8; 00182 case TYPE_BASIC_INT3264: 00183 if (typelib_kind == SYS_WIN64) 00184 { 00185 if (type_basic_get_sign(t) > 0) 00186 return VT_UI8; 00187 else 00188 return VT_I8; 00189 } 00190 else 00191 { 00192 if (type_basic_get_sign(t) > 0) 00193 return VT_UI4; 00194 else 00195 return VT_I4; 00196 } 00197 case TYPE_BASIC_FLOAT: 00198 return VT_R4; 00199 case TYPE_BASIC_DOUBLE: 00200 return VT_R8; 00201 case TYPE_BASIC_HANDLE: 00202 error("handles can't be used in typelibs\n"); 00203 } 00204 break; 00205 00206 case TYPE_POINTER: 00207 return VT_PTR; 00208 00209 case TYPE_ARRAY: 00210 if (type_array_is_decl_as_ptr(t)) 00211 { 00212 if (match(type_array_get_element(t)->name, "SAFEARRAY")) 00213 return VT_SAFEARRAY; 00214 } 00215 else 00216 error("get_type_vt: array types not supported\n"); 00217 return VT_PTR; 00218 00219 case TYPE_INTERFACE: 00220 if(match(t->name, "IUnknown")) 00221 return VT_UNKNOWN; 00222 if(match(t->name, "IDispatch")) 00223 return VT_DISPATCH; 00224 return VT_USERDEFINED; 00225 00226 case TYPE_ENUM: 00227 case TYPE_STRUCT: 00228 case TYPE_COCLASS: 00229 case TYPE_MODULE: 00230 case TYPE_UNION: 00231 case TYPE_ENCAPSULATED_UNION: 00232 return VT_USERDEFINED; 00233 00234 case TYPE_VOID: 00235 return VT_VOID; 00236 00237 case TYPE_ALIAS: 00238 /* aliases should be filtered out by the type_get_type call above */ 00239 assert(0); 00240 break; 00241 00242 case TYPE_FUNCTION: 00243 error("get_type_vt: functions not supported\n"); 00244 break; 00245 00246 case TYPE_BITFIELD: 00247 error("get_type_vt: bitfields not supported\n"); 00248 break; 00249 } 00250 return 0; 00251 } 00252 00253 void start_typelib(typelib_t *typelib_type) 00254 { 00255 if (!do_typelib) return; 00256 typelib = typelib_type; 00257 } 00258 00259 void end_typelib(void) 00260 { 00261 if (!typelib) return; 00262 00263 create_msft_typelib(typelib); 00264 } 00265 00266 static void tlb_read(int fd, void *buf, int count) 00267 { 00268 if(read(fd, buf, count) < count) 00269 error("error while reading importlib.\n"); 00270 } 00271 00272 static void tlb_lseek(int fd, off_t offset) 00273 { 00274 if(lseek(fd, offset, SEEK_SET) == -1) 00275 error("lseek failed\n"); 00276 } 00277 00278 static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid) 00279 { 00280 tlb_lseek(fd, segdir->pGuidTab.offset+offset); 00281 tlb_read(fd, guid, sizeof(GUID)); 00282 } 00283 00284 static void read_msft_importlib(importlib_t *importlib, int fd) 00285 { 00286 MSFT_Header header; 00287 MSFT_SegDir segdir; 00288 int *typeinfo_offs; 00289 int i; 00290 00291 importlib->allocated = 0; 00292 00293 tlb_lseek(fd, 0); 00294 tlb_read(fd, &header, sizeof(header)); 00295 00296 importlib->version = header.version; 00297 00298 typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT)); 00299 tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT)); 00300 tlb_read(fd, &segdir, sizeof(segdir)); 00301 00302 msft_read_guid(fd, &segdir, header.posguid, &importlib->guid); 00303 00304 importlib->ntypeinfos = header.nrtypeinfos; 00305 importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t)); 00306 00307 for(i=0; i < importlib->ntypeinfos; i++) { 00308 MSFT_TypeInfoBase base; 00309 MSFT_NameIntro nameintro; 00310 int len; 00311 00312 tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir) 00313 + typeinfo_offs[i]); 00314 tlb_read(fd, &base, sizeof(base)); 00315 00316 importlib->importinfos[i].importlib = importlib; 00317 importlib->importinfos[i].flags = (base.typekind&0xf)<<24; 00318 importlib->importinfos[i].offset = -1; 00319 importlib->importinfos[i].id = i; 00320 00321 if(base.posguid != -1) { 00322 importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; 00323 msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); 00324 } 00325 else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid)); 00326 00327 tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); 00328 tlb_read(fd, &nameintro, sizeof(nameintro)); 00329 00330 len = nameintro.namelen & 0xff; 00331 00332 importlib->importinfos[i].name = xmalloc(len+1); 00333 tlb_read(fd, importlib->importinfos[i].name, len); 00334 importlib->importinfos[i].name[len] = 0; 00335 } 00336 00337 free(typeinfo_offs); 00338 } 00339 00340 static void read_importlib(importlib_t *importlib) 00341 { 00342 int fd; 00343 INT magic; 00344 char *file_name; 00345 00346 file_name = wpp_find_include(importlib->name, NULL); 00347 if(file_name) { 00348 fd = open(file_name, O_RDONLY | O_BINARY ); 00349 free(file_name); 00350 }else { 00351 fd = open(importlib->name, O_RDONLY | O_BINARY ); 00352 } 00353 00354 if(fd < 0) 00355 error("Could not open importlib %s.\n", importlib->name); 00356 00357 tlb_read(fd, &magic, sizeof(magic)); 00358 00359 switch(magic) { 00360 case MSFT_MAGIC: 00361 read_msft_importlib(importlib, fd); 00362 break; 00363 default: 00364 error("Wrong or unsupported typelib magic %x\n", magic); 00365 }; 00366 00367 close(fd); 00368 } 00369 00370 void add_importlib(const char *name) 00371 { 00372 importlib_t *importlib; 00373 00374 if(!typelib) return; 00375 00376 LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry ) 00377 if(!strcmp(name, importlib->name)) 00378 return; 00379 00380 chat("add_importlib: %s\n", name); 00381 00382 importlib = xmalloc(sizeof(*importlib)); 00383 memset( importlib, 0, sizeof(*importlib) ); 00384 importlib->name = xstrdup(name); 00385 00386 read_importlib(importlib); 00387 list_add_head( &typelib->importlibs, &importlib->entry ); 00388 } Generated on Sat May 26 2012 04:24:18 for ReactOS by
1.7.6.1
|