| /* |
| genidl - Generate interface defintion language listing from a |
| Portable Executable. |
| Copyright (C) 2009-2016 mingw-w64 project |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program 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 General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| #define _CRT_SECURE_NO_WARNINGS |
| #include "genidl_cfg.h" |
| #include "genidl_typeinfo.h" |
| #include "genidl_typinfo.h" |
| |
| static void |
| fill_typb (sTI2TypLib *tl, sTI2TypeBase *tb, size_t off, unsigned char *dsrc, unsigned char *tdta, uint32_t length); |
| static void |
| print_typb_options (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix, const char *dllname); |
| static void |
| printInterfaceFuncVars (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix); |
| static void |
| printArgFlags (FILE *fp, uint32_t aflags); |
| static void |
| printFuncOption (FILE *fp, uint32_t flags, uint32_t id, uint32_t defid, |
| uint32_t funcKind, const char **fctPrefix, const char *prefix, |
| uint32_t invokeKind); |
| static void |
| printVarOption (FILE *fp, uint32_t flags, uint32_t id, uint32_t defid, |
| uint32_t varKind, const char **varPrefix, |
| const char *prefix); |
| static void |
| printEnum (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix_); |
| |
| void |
| TI2_typlib_dest (sTI2TypLib *tl) |
| { |
| if (!tl) |
| return; |
| TI_dest_typs (&tl->ti2_typs); |
| if (tl->guid) |
| free (tl->guid); |
| if (tl->helpstring) |
| free (tl->helpstring); |
| if (tl->helpfile) |
| free (tl->helpfile); |
| if (tl->name) |
| free (tl->name); |
| if (tl->typinfos_hash) |
| free (tl->typinfos_hash); |
| if (tl->typb) |
| { |
| size_t i; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| ; /* Clean typb */ |
| } |
| free (tl->typb); |
| } |
| free (tl); |
| } |
| |
| sTI2TypLib * |
| TI2_typlib_init (unsigned char *dta, size_t len) |
| { |
| sTI2TypLib *tl = NULL; |
| sTypeLibMSFT *t = (sTypeLibMSFT *) dta; |
| sSegMSFT *segs; |
| unsigned char *d; |
| int32_t *typeinfos; |
| int i = 0; |
| |
| if (!len || !dta || t->magic1 != TYPELIB_MSFT_MAGIC) |
| return NULL; |
| tl = (sTI2TypLib *) malloc (sizeof (sTI2TypLib)); |
| memset (tl, 0, sizeof (sTI2TypLib)); |
| TI_init_typs (&tl->ti2_typs); |
| |
| i = 0; |
| if (t->var_flags & 0x100) |
| i++; |
| typeinfos = (int32_t *) &t->dta[i]; |
| d = (unsigned char *) &typeinfos[t->nr_typeinfos]; |
| segs = (sSegMSFT *) d; |
| d = (unsigned char *) &segs[eSegMSFT_MAX]; |
| |
| /* Initialize constants pools. */ |
| TI2_import_name (&tl->ti2_typs,dta + segs[eSegMSFT_NAME].offset, segs[eSegMSFT_NAME].length); |
| TI2_import_string (&tl->ti2_typs,dta + segs[eSegMSFT_STRING].offset, segs[eSegMSFT_STRING].length); |
| TI2_import_guid (&tl->ti2_typs,dta + segs[eSegMSFT_GUID].offset, segs[eSegMSFT_GUID].length); |
| TI2_import_importlibs (&tl->ti2_typs, dta + segs[eSegMSFT_IMPORTFILES].offset, segs[eSegMSFT_IMPORTFILES].length); |
| TI2_import_importref (&tl->ti2_typs, dta + segs[eSegMSFT_IMPORTINFO].offset, segs[eSegMSFT_IMPORTINFO].length); |
| TI2_import_typinfo_names (&tl->ti2_typs, |
| dta + segs[eSegMSFT_TYPEINFO].offset, segs[eSegMSFT_TYPEINFO].length); |
| TI2_import_typedesc (&tl->ti2_typs,dta + segs[eSegMSFT_TYPEDESC].offset, segs[eSegMSFT_TYPEDESC].length); |
| TI2_import_customdata (&tl->ti2_typs, dta + segs[eSegMSFT_CUSTDATA].offset, segs[eSegMSFT_CUSTDATA].length); |
| TI2_import_array (&tl->ti2_typs, dta + segs[eSegMSFT_ARRAYDESC].offset, segs[eSegMSFT_ARRAYDESC].length); |
| TI2_import_ref (&tl->ti2_typs, dta + segs[eSegMSFT_REFERENCES].offset, segs[eSegMSFT_REFERENCES].length); |
| TI2_import_customdataguid (&tl->ti2_typs, dta + segs[eSegMSFT_CUSTDATAGUID].offset, segs[eSegMSFT_CUSTDATAGUID].length); |
| |
| tl->ver_major = t->ver_major; |
| tl->ver_minor = t->ver_minor; |
| tl->version = t->version; |
| tl->lcid1 = t->lcid; |
| tl->lcid2 = t->lcid2; |
| if (t->pos_guid != -1) |
| tl->guid = TI_get_typ_name (&tl->ti2_typs, t->pos_guid, TITYP_GUIDS, ""); |
| tl->flags = t->flags; |
| tl->setFlags = t->var_flags; |
| tl->helpstringctx = t->helpstringcontext; |
| tl->helpctx = t->helpcontext; |
| if (t->helpstring != -1) |
| tl->helpstring = TI_get_typ_name (&tl->ti2_typs, t->helpstring, TITYP_STR, ""); |
| if (t->helpfile != -1) |
| tl->helpfile = TI_get_typ_name (&tl->ti2_typs, t->helpfile, TITYP_STR, ""); |
| if (t->name_offset != -1) |
| { |
| tl->name = TI_get_typ_name (&tl->ti2_typs, t->name_offset, TITYP_NAME, ""); |
| genidl_strlwr (tl->name); |
| } |
| tl->dispatch = t->dispatchpos; |
| tl->nr_typinfos = t->nr_typeinfos; |
| tl->nr_impinfos = t->nr_impinfos; |
| if (tl->nr_typinfos > 0) |
| { |
| size_t ii; |
| tl->typinfos_hash = (uint32_t *) malloc (sizeof (uint32_t) * tl->nr_typinfos); |
| memcpy (tl->typinfos_hash, typeinfos, sizeof (uint32_t) * tl->nr_typinfos); |
| tl->typb = (sTI2TypeBase *) malloc (sizeof (sTI2TypeBase) * tl->nr_typinfos); |
| memset (tl->typb, 0, sizeof (sTI2TypeBase) * tl->nr_typinfos); |
| for (ii = 0;ii < tl->nr_typinfos; ii++) |
| { |
| fill_typb (tl, &tl->typb[ii], ii, dta, dta + segs[eSegMSFT_TYPEINFO].offset, segs[eSegMSFT_TYPEINFO].length); |
| } |
| } |
| return tl; |
| } |
| |
| static void |
| fill_typb (sTI2TypLib *tl, sTI2TypeBase *tb, size_t off, unsigned char *dsrc, unsigned char *tdta, uint32_t length) |
| { |
| sMSFT_TypeInfoBase *t = (sMSFT_TypeInfoBase *) &tdta[off * sizeof (sMSFT_TypeInfoBase)]; |
| if (length <= (off * sizeof (sMSFT_TypeInfoBase))) |
| return; |
| tb->kind = (t->typekind & 0xf); |
| tb->kflags = (t->typekind >> 4) & 0xfff; |
| tb->flags= t->flags; |
| tb->cFuncs = t->cElement & 0xffff; |
| tb->cVars = (t->cElement >> 16) & 0xffff; |
| tb->name = TI_get_typ_name (&tl->ti2_typs, (uint32_t) (off * sizeof (sMSFT_TypeInfoBase)), |
| TITYP_TYPINFO_NAMES, ""); |
| if (t->posguid != -1) |
| tb->guid = TI_get_typ_name (&tl->ti2_typs, (uint32_t) t->posguid, TITYP_GUIDS, ""); |
| if (t->docstringoffs != -1) |
| tb->docstr = TI_get_typ_name (&tl->ti2_typs, (uint32_t) t->docstringoffs, TITYP_STR, ""); |
| if (t->oCustData != -1) |
| tb->custData = TI_get_typ_name (&tl->ti2_typs, (uint32_t) t->oCustData, |
| TITYP_CUSTOMDATA, ""); |
| tb->version = t->version; |
| if (t->datatype1 != -1) |
| { |
| switch (tb->kind) |
| { |
| case TKIND_COCLASS: |
| tb->dataType = |
| TI_get_typ_name (&tl->ti2_typs, (uint32_t) t->datatype1, TITYP_REF, ""); |
| break; |
| case TKIND_MODULE: |
| tb->dataType = |
| TI_get_typ_name (&tl->ti2_typs, (uint32_t) t->datatype1, TITYP_STR, ""); |
| break; |
| case TKIND_INTERFACE: |
| case TKIND_DISPATCH: |
| tb->dataType = |
| getTypeBOrImpRef (&tl->ti2_typs, (uint32_t) t->datatype1,""); |
| break; |
| default: |
| tb->dataType = |
| TI_getVTorDref (&tl->ti2_typs, (uint32_t) t->datatype1, "", 0); |
| break; |
| } |
| } |
| tb->tib = t; |
| if (tb->cFuncs || tb->cVars) |
| { |
| sMSFT_memblob *b = (sMSFT_memblob *) &dsrc[t->memoffset]; |
| uint32_t *doff = (uint32_t *) &b->dta[b->size]; |
| uint32_t offs = 0; |
| size_t cf = tb->cFuncs; |
| size_t cv = tb->cVars; |
| size_t idx = 0; |
| tb->mem.count = cf + cv; |
| tb->mem.items = (sTI2TypeBaseMemItem *) |
| malloc ( sizeof (sTI2TypeBaseMemItem) * tb->mem.count); |
| memset (tb->mem.items, 0, sizeof (sTI2TypeBaseMemItem) * tb->mem.count); |
| while (offs < b->size) |
| { |
| tb->mem.items[idx].mem = &b->dta[offs]; |
| if (cf > 0) |
| { |
| sMSFT_FuncParam *params; |
| sMSFT_func *func; |
| uint32_t oVars = 0, *pData, *pCustomData = NULL; |
| |
| func = (sMSFT_func *) &b->dta[offs]; |
| oVars = func->rlen - (func->nrArgs * 12); |
| params = (sMSFT_FuncParam *) &b->dta[offs + oVars]; |
| pData = func->data; |
| pCustomData = NULL; |
| if (func->f.hasParamDefValue) |
| pCustomData = (uint32_t *) &b->dta[offs + oVars-func->nrArgs*4]; |
| tb->mem.items[idx].customData = pCustomData; |
| tb->mem.items[idx].funcParam = params; |
| tb->mem.items[idx].extData = doff; |
| tb->mem.items[idx].max = tb->mem.count; |
| tb->mem.items[idx].beFunc = 1; |
| offs += func->rlen; |
| --cf; |
| } |
| else if (cv > 0) |
| { |
| sMSFT_var *var = (sMSFT_var *) &b->dta[offs]; |
| offs += var->rlen; |
| tb->mem.items[idx].extData = doff; |
| tb->mem.items[idx].max = tb->mem.count; |
| } |
| else |
| abort (); |
| doff++; |
| idx++; |
| } |
| } |
| } |
| |
| static void |
| TI2_update_config (sTI2TypLib *tl, const char *orgfname) |
| { |
| size_t no = tl->nr_typinfos; |
| size_t i; |
| char *tlbname; |
| char *sec = NULL; |
| |
| genidl_add_lib (tl->name); |
| sec = (char *) malloc (strlen (orgfname) + 5); |
| /* Do we have a .tlb input file? If so add alias of name. */ |
| strcpy (sec, orgfname); |
| if (strrchr (sec, '.') != NULL) |
| { |
| if (strcmp (strrchr (sec, '.'), ".tlb") != 0) |
| strcpy (strrchr (sec, '.'), ".tlb"); |
| } |
| else |
| { |
| strcat (sec, ".tlb"); |
| } |
| genidl_add_lib_alias (sec, tl->name); |
| free (sec); |
| |
| /* We remove possibly old items. */ |
| genidl_del_lib_item (tl->name); |
| if (!no && tl->ti2_typs.buc[TITYP_NAME].count != 0 |
| && tl->ti2_typs.buc[TITYP_GUIDS].count != 0) |
| return; |
| tlbname = (char *) malloc (strlen ("TypeD_") + 8 + 1); |
| *tlbname = 0; |
| |
| for (i = 0;i < no; i++) |
| { |
| /* uint32_t mem = tl->ti2_typs.buc[TITYP_TYPINFO_NAMES].arr[i]->memid; */ |
| char *name = tl->ti2_typs.buc[TITYP_TYPINFO_NAMES].arr[i]->name; |
| /* sprintf (tlbname, "TypeB_%x", mem); */ |
| sprintf (tlbname, "TypeB_%x", (unsigned int) i); |
| genidl_add_lib_item (tl->name, tlbname, name); |
| |
| if (tl->typb[i].guid) |
| { |
| char *hp = strdup (tl->typb[i].guid + 1); |
| if (strrchr (hp, '\"') != NULL) |
| * strrchr (hp, '\"') = 0; |
| genidl_add_lib_item (tl->name, hp, name); |
| free (hp); |
| } |
| /*if (tl->typb[i].tib->NameOffset != -1) |
| { |
| sprintf (tlbname, "Name_%x", tl->typb[i].tib->NameOffset); |
| genidl_add_lib_item (tl->name, tlbname, name); |
| } */ |
| } |
| free (tlbname); |
| } |
| |
| static int |
| printVersion (FILE *fp, uint32_t version, int befirst, int befirstret, const char *prefix) |
| { |
| if (befirst == 0) |
| fprintf (fp, ",\n%s ", prefix); |
| else if (befirst == -1) |
| fprintf (fp, ", "); |
| else if (befirstret == 0) |
| fprintf (fp, "%s ", prefix); |
| fprintf (fp,"version(%d.%d)", version & 0xffff, (version>>16) & 0xffff); |
| return befirstret; |
| } |
| |
| static int |
| print_flagsstring (FILE *fp, const char *attr, int befirst, int befirstret, const char *prefix) |
| { |
| if (befirst == 0) |
| fprintf (fp, ",\n%s ", prefix); |
| else if (befirst == -1) |
| fprintf (fp, ", "); |
| else if (befirstret == 0) |
| fprintf (fp, "%s ", prefix); |
| fprintf (fp, "%s", attr); |
| return befirstret; |
| } |
| |
| static int |
| printString (FILE *fp, const char *name, const char *str, int befirst, int befirstret, const char *prefix) |
| { |
| if (befirst == 0) |
| fprintf (fp, ",\n%s ", prefix); |
| else if (befirst == -1) |
| fprintf (fp, ", "); |
| else if (befirstret == 0) |
| fprintf (fp, "%s ", prefix); |
| if (!str) str = ""; |
| if (*str != '"') |
| fprintf (fp, "%s(\"%s\")", name, str); |
| else |
| fprintf (fp, "%s(%s)", name, str); |
| return befirstret; |
| } |
| |
| static int |
| printUuid (FILE *fp, char *str,int befirst,int befirstret, const char *prefix) |
| { |
| if (befirst == 0) |
| fprintf (fp, ",\n%prefix ", prefix); |
| else if (befirst == -1) |
| fprintf (fp, ", "); |
| else if (befirstret == 0) |
| fprintf (fp, "%s ", prefix); |
| if (!str || (str[0] == '"' && str[1]=='"')) |
| fprintf (fp, "uuid(00000000-0000-0000-0000-000000000000)"); |
| else if (*str != '"') |
| { |
| fprintf (fp, "uuid(%s)", str); |
| } |
| else |
| { |
| str++; |
| fprintf (fp, "uuid("); |
| while (*str != 0 && *str != '"') |
| { |
| fputc (*str,fp); |
| ++str; |
| } |
| fprintf (fp, ")"); |
| } |
| return befirstret; |
| } |
| |
| static const char *varflags[32] = { |
| "readonly", "source", "bindable", "requestedit", |
| "displaybind", "defaultbind", "hidden", "restricted", |
| "defaultcollelem", "uidefault", "nonbrowsable", "replaceable", |
| "immediatebind", "VARFLAG_2000","VARFLAG_4000","VARFLAG_8000", |
| "VARFLAG_10000","VARFLAG_20000","VARFLAG_40000","VARFLAG_80000", |
| "VARFLAG_100000","VARFLAG_200000","VARFLAG_400000","VARFLAG_800000", |
| "VARFLAG_1000000","VARFLAG_2000000","VARFLAG_4000000","VARFLAG_8000000", |
| "VARFLAG_10000000","VARFLAG_20000000","VARFLAG_40000000","VARFLAG_80000000" |
| }; |
| |
| static const char *funcflags[32] = |
| { |
| "restricted", "source", "bindable", "requestedit", |
| "displaybind", "defaultbind", "hidden", "uselasterror", |
| "defaultcollelem", "uidefault", "nonbrowsable", "replaceable", |
| "immediatebind", "FUNCFLAG_2000","FUNCFLAG_4000","FUNCFLAG_8000", |
| "FUNCFLAG_10000","FUNCFLAG_20000","FUNCFLAG_40000","FUNCFLAG_80000", |
| "FUNCFLAG_100000","FUNCFLAG_200000","FUNCFLAG_400000","FUNCFLAG_800000", |
| "FUNCFLAG_1000000","FUNCFLAG_2000000","FUNCFLAG_4000000","FUNCFLAG_8000000", |
| "FUNCFLAG_10000000","FUNCFLAG_20000000","FUNCFLAG_40000000","FUNCFLAG_80000000" |
| }; |
| |
| static const char *typb_flags[32] = { |
| "appobject", "cancreate", "licensed", "predeclid", |
| "hidden", "control", "dual", "nonextensible", |
| "oleautomation", "restricted", "aggregatable", "replaceable", |
| "dispatchable", "reversebind", "proxy", "TYPEFLAG_8000", |
| "TYPEFLAG_10000","TYPEFLAG_20000","TYPEFLAG_40000","TYPEFLAG_80000", |
| "TYPEFLAG_100000","TYPEFLAG_200000","TYPEFLAG_400000","TYPEFLAG_800000", |
| "TYPEFLAG_1000000","TYPEFLAG_2000000","TYPEFLAG_4000000","TYPEFLAG_8000000", |
| "TYPEFLAG_10000000","TYPEFLAG_20000000","TYPEFLAG_40000000","TYPEFLAG_80000000" |
| }; |
| |
| static const char *param_flags[32] = { |
| "in", "out", "lcid", "retval", |
| "opt", "\0hasdefault", "hascustomdata", "PARAMFLAG_80", |
| "PARAMFLAG_100","PARAMFLAG_200","PARAMFLAG_400","PARAMFLAG_800", |
| "PARAMFLAG_1000","PARAMFLAG_2000","PARAMFLAG_4000","PARAMFLAG_8000", |
| "PARAMFLAG_10000","PARAMFLAG_20000","PARAMFLAG_40000","PARAMFLAG_80000", |
| "PARAMFLAG_100000","PARAMFLAG_200000","PARAMFLAG_400000","PARAMFLAG_800000", |
| "PARAMFLAG_1000000","PARAMFLAG_2000000","PARAMFLAG_4000000","PARAMFLAG_8000000", |
| "PARAMFLAG_10000000","PARAMFLAG_20000000","PARAMFLAG_40000000","PARAMFLAG_80000000" |
| }; |
| |
| static void |
| printArgFlags (FILE *fp, uint32_t aflags) |
| { |
| int idx = 0, befirst = 1; |
| if (!aflags || (aflags & ~PARAMFLAG_FHASDEFAULT)==0) |
| return; |
| fprintf (fp, "["); |
| while (aflags != 0 && idx < 32) |
| { |
| if ((aflags & 1)!=0 && param_flags[idx][0] != 0) |
| { |
| fprintf (fp, "%s%s", befirst ? "" : " ", param_flags[idx]); |
| befirst = 0; |
| } |
| aflags >>= 1; |
| idx++; |
| } |
| fprintf (fp, "] "); |
| } |
| |
| static void |
| print_typb_options (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix, const char *dllname) |
| { |
| int befirst = 1; |
| uint32_t flags = tb->flags, idx = 0; |
| |
| if (tl) |
| befirst = 1; |
| if (!tb) |
| return; |
| if (tb->flags == 0 && tb->docstr == NULL && tb->guid == NULL |
| && tb->version == 0 && dllname == NULL) |
| return; |
| fprintf (fp, "%s[\n", prefix); |
| if (tb->guid != NULL) |
| befirst = printUuid (fp, tb->guid,befirst, 0, prefix); |
| if (tb->version != 0) |
| befirst = printVersion (fp, tb->version, befirst, 0, prefix); |
| if (tb->docstr) |
| befirst = printString (fp, "helpstring", tb->docstr, befirst, 0, prefix); |
| while (flags != 0 && idx != 32) |
| { |
| if ((flags & 1) != 0 && typb_flags[idx][0] != 0) |
| befirst = print_flagsstring (fp, typb_flags[idx], befirst, 0, prefix); |
| flags >>= 1; idx++; |
| } |
| if (dllname) |
| befirst = printString (fp, "dllname", dllname, befirst, 0, prefix); |
| if (befirst != 1) |
| fprintf (fp, "\n"); |
| fprintf (fp, "%s]\n", prefix); |
| } |
| |
| static void |
| TI2_typlib_imports (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| sTITypsHash *th = &tl->ti2_typs.buc[TITYP_IMP]; |
| for (i = 0;i < th->count; i++) |
| { |
| fprintf (fp, "%simportlib(\"%s\");\n", prefix, th->arr[i]->name); |
| } |
| if (i != 0) |
| fprintf (fp, "\n"); |
| } |
| |
| static char *mk_guard (const char *name, const char *addition) |
| { |
| char *r, *h; |
| size_t len; |
| if (!addition) |
| addition = ""; |
| len = strlen (name) + strlen (addition) + 1 + strlen ("__"); |
| r = (char *) malloc (len); |
| sprintf (r, "__%s%s", name, addition); |
| h = r; |
| while (*h != 0) |
| { |
| if (*h >= 'a' && *h <= 'z') |
| { |
| h[0] -= 'a'; |
| h[0] += 'A'; |
| } |
| else if (*h <= 0x20) |
| *h = '_'; |
| h++; |
| } |
| return r; |
| } |
| |
| static void |
| TI2_typlib_forward_declare (FILE *fp, sTI2TypLib *tl, int behdr) |
| { |
| size_t i; |
| char *guard = NULL; |
| int befirst; |
| befirst = 1; |
| if (!behdr) |
| { |
| /* |
| fprintf (fp, "/ * Typedef definitions of basic types. * /\n" |
| "typedef unsigned short USHORT;\n" |
| "typedef signed short SHORT;\n" |
| "typedef unsigned char UCHAR;\n" |
| "typedef signed char CHAR;\n" |
| "typedef unsigned int UINT;\n" |
| "typedef signed int INT;\n" |
| "typedef int WINBOOL;\n" |
| "typedef struct _tagVARIANT VARIANT;\n" |
| "typedef unsigned short *BSTR;\n" |
| "typedef int SCODE;\n" |
| "typedef struct _CY CY;\n"); |
| */ |
| } |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_INTERFACE) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "/* Interface forward declarations. */\n"); |
| befirst = 0; |
| } |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_FORWARDER_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%s;\n", tl->typb[i].name); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| char *hn; |
| if (tl->typb[i].kind != TKIND_RECORD) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "/* Structure forward declarations. */\n"); |
| befirst = 0; |
| } |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_FORWARDER_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| if ((hn = strchr (tl->typb[i].name, ' ')) == NULL) |
| hn = tl->typb[i].name; |
| else hn++; |
| fprintf (fp, "typedef %s %s;\n", tl->typb[i].name, hn); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| char *hn; |
| if (tl->typb[i].kind != TKIND_UNION) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "/* Union record forward declarations. */\n"); |
| befirst = 0; |
| } |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_FORWARDER_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| if ((hn = strchr (tl->typb[i].name, ' ')) == NULL) |
| hn = tl->typb[i].name; |
| else hn++; |
| fprintf (fp, "typedef %s %s;\n", tl->typb[i].name, hn); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_DISPATCH) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "/* Dispatch record forward declarations. */\n"); |
| befirst = 0; |
| } |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_FORWARDER_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%s;\n", tl->typb[i].name); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_COCLASS) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "/* Coclass record forward declarations. */\n"); |
| befirst = 0; |
| } |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_FORWARDER_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%s;\n", tl->typb[i].name); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_typedefs (FILE *fp, sTI2TypLib *tl, const char *prefix, int behdr) |
| { |
| char *guard = NULL; |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_ALIAS) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Type definitions. */\n", prefix); |
| befirst = 0; |
| } |
| if (!behdr) |
| print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_TYPEDEF_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%stypedef %s %s;\n", prefix, |
| (tl->typb[i].dataType ? tl->typb[i].dataType : "<unknown>"), |
| tl->typb[i].name); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp,"#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_enumerations (FILE *fp, sTI2TypLib *tl, const char *prefix, int behdr) |
| { |
| char *guard = NULL; |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_ENUM) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Enumeration declarations. */\n", prefix); |
| befirst = 0; |
| } |
| if (!behdr) |
| print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%s%s\n", prefix, tl->typb[i].name); |
| fprintf (fp, "%s{\n", prefix); |
| printEnum (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp, "#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_dispinterface_hdr (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_DISPATCH) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Dispatch interface declarations. */\n", prefix); |
| befirst = 0; |
| } |
| //print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| fprintf (fp, "%s%s", prefix, tl->typb[i].name); |
| if (tl->typb[i].dataType != NULL) |
| { |
| char *h = tl->typb[i].dataType; |
| if (strchr (h, ' ')!=NULL) |
| h = strchr (h, ' ') + 1; |
| fprintf (fp, " : %s", h); |
| } |
| fprintf (fp, "\n"); |
| fprintf (fp, "%s{\n", prefix); |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_dispinterface (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_DISPATCH) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Dispatch interface declarations. */\n", prefix); |
| befirst = 0; |
| } |
| print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| fprintf (fp, "%s%s", prefix, tl->typb[i].name); |
| if (tl->typb[i].dataType != NULL) |
| { |
| char *h = tl->typb[i].dataType; |
| if (strchr (h, ' ')!=NULL) |
| h = strchr (h, ' ') + 1; |
| fprintf (fp, " : %s", h); |
| } |
| fprintf (fp, "\n"); |
| fprintf (fp, "%s{\n", prefix); |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_coclass_hdr (FILE *fp, sTI2TypLib *tl, const char *prefix, uint32_t tkind) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != tkind) |
| continue; |
| if (befirst) |
| { |
| if (tkind == TKIND_COCLASS) |
| fprintf (fp, "%s/* CoClass declarations. */\n", prefix); |
| befirst = 0; |
| } |
| //print_typb_options (fp,tl,&tl->typb[i],prefix, NULL); |
| fprintf (fp, "%s%s\n", prefix, tl->typb[i].name); |
| fprintf (fp, "%s{\n", prefix); |
| if (tl->typb[i].tib->datatype1 != -1) |
| { |
| int offset_ref = tl->typb[i].tib->datatype1; |
| char *ifname; |
| sTITyp *rtyp; |
| do { |
| rtyp = TI_get_typ (&tl->ti2_typs, (uint32_t) offset_ref, TITYP_REF); |
| ifname = TI_get_typ_name (&tl->ti2_typs, (uint32_t) offset_ref, TITYP_REF, ""); |
| offset_ref = (rtyp == NULL ? -1 : (int) rtyp->refmem); |
| if (ifname) |
| fprintf (fp, "%s %s;\n",prefix,ifname); |
| } while (offset_ref != -1); |
| |
| } |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_coclass (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_COCLASS) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* CoClass declarations. */\n", prefix); |
| befirst = 0; |
| } |
| print_typb_options (fp,tl,&tl->typb[i],prefix, NULL); |
| fprintf (fp, "%s%s\n", prefix, tl->typb[i].name); |
| fprintf (fp, "%s{\n", prefix); |
| if (tl->typb[i].tib->datatype1 != -1) |
| { |
| int offset_ref = tl->typb[i].tib->datatype1; |
| char *ifname; |
| sTITyp *rtyp; |
| do { |
| rtyp = TI_get_typ (&tl->ti2_typs, (uint32_t) offset_ref, TITYP_REF); |
| ifname = TI_get_typ_name (&tl->ti2_typs, (uint32_t) offset_ref, TITYP_REF, ""); |
| offset_ref = (rtyp == NULL ? -1 : (int) rtyp->refmem); |
| if (ifname) |
| fprintf (fp, "%s %s;\n",prefix,ifname); |
| } while (offset_ref != -1); |
| |
| } |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_structures (FILE *fp, sTI2TypLib *tl, const char *prefix, int behdr) |
| { |
| char *guard = NULL; |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_RECORD && tl->typb[i].kind != TKIND_UNION) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Structure/union declarations. */\n", prefix); |
| befirst = 0; |
| } |
| if (!behdr) |
| print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| if (behdr) |
| guard = mk_guard (tl->typb[i].name, "_DEFINED"); |
| if (guard && *guard != 0) |
| fprintf (fp, "#ifndef %s\n#define %s\n", guard, guard); |
| fprintf (fp, "%s%s\n", prefix, tl->typb[i].name); |
| fprintf (fp, "%s{\n", prefix); |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| if (guard) |
| { |
| if (*guard != 0) |
| fprintf (fp, "#endif /* %s */\n\n", guard); |
| free (guard); |
| guard = NULL; |
| } |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| TI2_typlib_modules (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_MODULE) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Module declarations. */\n", prefix); |
| befirst = 0; |
| } |
| print_typb_options (fp,tl, &tl->typb[i],prefix, tl->typb[i].dataType); |
| fprintf (fp, "%s%s", prefix, tl->typb[i].name); |
| fprintf (fp, "\n"); |
| fprintf (fp, "%s{\n", prefix); |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| printEnum (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix_) |
| { |
| char *prefix; |
| size_t i; |
| if (!tl || !tb || (tb->cFuncs == 0 && tb->cVars == 0)) |
| return; |
| prefix = (char *) malloc (strlen (prefix_) + 3); |
| memset (prefix,' ',strlen (prefix_) + 2); |
| prefix[strlen (prefix_) + 2] = 0; |
| |
| for (i = 0;i < tb->mem.count; i++) |
| { |
| char *name = NULL; |
| sTI2TypeBaseMemItem *mi = &tb->mem.items[i]; |
| |
| name = TI_get_typ_name (&tl->ti2_typs, mi->extData[mi->max], TITYP_NAME, ""); |
| if (mi->beFunc) |
| { |
| abort (); |
| } |
| else |
| { |
| fprintf (fp, "%s%s = ", prefix, name); |
| printValue (fp, &tl->ti2_typs,mi->var->oValue); |
| fprintf (fp, "%s\n", ((i+1) != tb->mem.count ? "," : "")); |
| } |
| if (name) |
| free (name); |
| } |
| free (prefix); |
| } |
| |
| static void |
| printInterfaceFuncVars (FILE *fp, sTI2TypLib *tl, sTI2TypeBase *tb, const char *prefix_) |
| { |
| uint32_t defid; |
| char *prefix; |
| size_t i; |
| if (!tl || !tb || (tb->cFuncs == 0 && tb->cVars == 0)) |
| return; |
| prefix = (char *) malloc (strlen (prefix_) + 3); |
| memset (prefix,' ',strlen (prefix_) + 2); |
| prefix[strlen (prefix_) + 2] = 0; |
| |
| switch (tb->kind) |
| { |
| case TKIND_UNION: case TKIND_RECORD: |
| defid = (uint32_t) 1073741824; break; |
| default: |
| defid = 0xfefefefe; break; |
| } |
| |
| for (i = 0;i < tb->mem.count; i++) |
| { |
| char *name = NULL; |
| char *rtyp = NULL; |
| uint32_t id; |
| sTI2TypeBaseMemItem *mi = &tb->mem.items[i]; |
| |
| name = TI_get_typ_name (&tl->ti2_typs, mi->extData[mi->max], TITYP_NAME, ""); |
| id = mi->extData[0]; |
| if (mi->beFunc) |
| { |
| const char *val = ""; |
| printFuncOption (fp, mi->func->flags, id, defid, mi->func->f.funcKind, &val, prefix, |
| mi->func->f.invokeKind); |
| rtyp = TI_getVTorDref (&tl->ti2_typs, mi->func->datatype, "", 0); |
| fprintf (fp, "%s%s%s %s %s (", |
| prefix, val, rtyp, getCallConvName(mi->func->f.callconv), |
| name); |
| if (mi->func->nrArgs == 0) |
| fprintf (fp, "void);\n"); |
| else |
| { |
| uint16_t a; |
| fprintf (fp, "\n"); |
| for (a = 0; a < mi->func->nrArgs;a++) |
| { |
| char *aname = NULL; |
| char *atyp = NULL; |
| if (mi->funcParam[a].oName != -1) |
| aname = TI_get_typ_name (&tl->ti2_typs, mi->funcParam[a].oName, TITYP_NAME, ""); |
| else |
| { |
| /* We have to generate an name for this argument. */ |
| aname = (char *) malloc (128); |
| sprintf (aname, "argNo%u", (uint32_t) a + 1); |
| } |
| atyp = TI_getVTorDref (&tl->ti2_typs, mi->funcParam[a].dataType, aname, 0); |
| fprintf (fp, "%s ", prefix); |
| printArgFlags (fp, mi->funcParam[a].flags); |
| fprintf (fp, "%s", atyp); |
| free (atyp); |
| free (aname); |
| if (mi->customData && (mi->funcParam[a].flags & PARAMFLAG_FHASDEFAULT) != 0) |
| { |
| fprintf (fp," = "); |
| printValue (fp, &tl->ti2_typs,mi->customData[a]); |
| } |
| if ((a + 1) != mi->func->nrArgs) |
| fprintf (fp, ","); |
| fprintf (fp, "\n"); |
| } |
| fprintf (fp, "%s);\n", prefix); |
| } |
| } |
| else |
| { |
| const char *val = ""; |
| printVarOption (fp, mi->var->flags, id, defid, mi->var->varKind, &val, prefix); |
| rtyp = TI_getVTorDref (&tl->ti2_typs, mi->var->datatype, name, 0); |
| fprintf (fp, "%s%s%s", prefix, val, rtyp); |
| if ((tb->kind == TKIND_DISPATCH || tb->kind == TKIND_INTERFACE) && mi->var->oValue != 0) |
| { |
| fprintf (fp," = %d", mi->var->oValue); |
| } |
| else if (tb->kind != TKIND_RECORD && tb->kind != TKIND_UNION |
| && !(tb->kind == TKIND_DISPATCH || tb->kind == TKIND_INTERFACE) |
| && (uint32_t) mi->var->oValue != (uint32_t) -1) |
| { |
| fprintf (fp," = "); |
| printValue (fp, &tl->ti2_typs,mi->var->oValue); |
| } |
| fprintf (fp, ";\n"); |
| } |
| if (rtyp) |
| free (rtyp); |
| if (name) |
| free (name); |
| defid = id + 1; |
| } |
| free (prefix); |
| } |
| |
| static void |
| TI2_typlib_interfaces (FILE *fp, sTI2TypLib *tl, const char *prefix) |
| { |
| size_t i; |
| int befirst; |
| befirst = 1; |
| for (i=0;i<tl->nr_typinfos;i++) |
| { |
| if (tl->typb[i].kind != TKIND_INTERFACE) |
| continue; |
| if (befirst) |
| { |
| fprintf (fp, "%s/* Interface declarations. */\n", prefix); |
| befirst = 0; |
| } |
| print_typb_options (fp,tl, &tl->typb[i],prefix, NULL); |
| fprintf (fp, "%s%s", prefix, tl->typb[i].name); |
| if (tl->typb[i].dataType != NULL) |
| { |
| char *h = tl->typb[i].dataType; |
| if (strchr (h, ' ')!=NULL) |
| h = strchr (h, ' ') + 1; |
| fprintf (fp, " : %s", h); |
| } |
| fprintf (fp, "\n"); |
| fprintf (fp, "%s{\n", prefix); |
| printInterfaceFuncVars (fp, tl, &tl->typb[i], prefix); |
| fprintf (fp, "%s};\n", prefix); |
| } |
| if (!befirst) |
| fprintf (fp, "\n"); |
| } |
| |
| static void |
| printVarOption (FILE *fp, uint32_t flags, uint32_t id, uint32_t defid, |
| uint32_t varKind, const char **varPrefix, |
| const char *prefix) |
| { |
| int befirst = 1,idx = 0; |
| |
| switch (varKind) { |
| case VARKIND_PERINSTANCE: break; |
| case VARKIND_STATIC: *varPrefix = "static "; break; |
| case VARKIND_CONST: *varPrefix = "CONST "; break; |
| case VARKIND_DISPATCH: break; |
| } |
| if (id == defid && flags == 0) |
| return; |
| fprintf (fp, "%s[", prefix); |
| if (id != defid) |
| { |
| if (id < 0x100) |
| fprintf (fp, "id(%u)", id); |
| else |
| fprintf (fp, "id(0x%x)", id); |
| befirst=0; |
| } |
| while (flags != 0) |
| { |
| if ((flags & 1)!=0 && varflags[idx][0]!=0) |
| { |
| if (!befirst) fprintf (fp, ", "); |
| befirst = 0; |
| fprintf (fp, "%s", varflags[idx]); |
| } |
| flags >>=1; idx++; |
| } |
| fprintf (fp, "]\n"); |
| } |
| |
| static void |
| printFuncOption (FILE *fp, uint32_t flags, uint32_t id, uint32_t defid, |
| uint32_t funcKind, const char **fctPrefix, const char *prefix, |
| uint32_t invokeKind) |
| { |
| int befirst = 1, idx = 0; |
| const char *invoke = ""; |
| switch (funcKind) |
| { |
| case FUNCTKIND_VIRTUAL: *fctPrefix = "virtual "; break; |
| case FUNCTKIND_PUREVIRTUAL: break; |
| case FUNCTKIND_NONVIRTUAL: break; |
| case FUNCTKIND_STATIC: *fctPrefix = "static "; break; |
| case FUNCTKIND_DISPATCH: |
| break; |
| } |
| switch ((invokeKind & ~1)) |
| { |
| case INVOKIND_FUNC: break; |
| case INVOKIND_PROPERTYGET: invoke = "propget"; break; |
| case INVOKIND_PROPERTYPUT: invoke = "propput"; break; |
| case INVOKIND_PROPERTYGET | INVOKIND_PROPERTYPUT: |
| invoke = "propgetput"; break; |
| case INVOKIND_PROPERTYPUTREF: |
| invoke = "propputref"; break; |
| case INVOKIND_PROPERTYPUT | INVOKIND_PROPERTYPUTREF: |
| invoke = "propputputref"; break; |
| case INVOKIND_PROPERTYGET | INVOKIND_PROPERTYPUTREF: |
| invoke = "propgetputref"; break; |
| case INVOKIND_PROPERTYGET | INVOKIND_PROPERTYPUT | INVOKIND_PROPERTYPUTREF: |
| invoke = "propgetputputref"; break; |
| } |
| if (id == defid && flags == 0 && invoke[0]==0) |
| return; |
| fprintf (fp, "%s[", prefix); |
| if (id != defid) |
| { |
| if (id < 0x100) |
| fprintf (fp, "id(%u)", id); |
| else |
| fprintf (fp, "id(0x%x)", id); |
| befirst = 0; |
| } |
| if (invoke[0]!=0) |
| { |
| if (!befirst) |
| fprintf (fp, ", "); |
| fprintf (fp, "%s", invoke); |
| befirst = 0; |
| } |
| while (flags != 0) |
| { |
| if ((flags & 1) != 0 && funcflags[idx][0]!=0) |
| { |
| if (!befirst) |
| fprintf (fp, ", "); |
| fprintf (fp, "%s", funcflags[idx]); |
| befirst = 0; |
| } |
| flags >>=1; idx++; |
| } |
| fprintf (fp, "]\n"); |
| } |
| |
| void |
| TI2_typlib_hdr (FILE *fp, sTI2TypLib *tl, const char *orgfname) |
| { |
| //int befirst; |
| if (!tl) |
| return; |
| fprintf (fp, "/* Automated generated header file <%s>.\n" |
| " * Generated by genidl tool (c) 2009-2016 Mingw-w64 project.\n" |
| " */\n\n", (tl->name ? tl->name : "unknown")); |
| TI2_update_config (tl, orgfname); |
| TI2_typlib_forward_declare (fp, tl, 1); |
| TI2_typlib_enumerations (fp, tl, "", 1); |
| TI2_typlib_structures (fp, tl, "",1); |
| TI2_typlib_typedefs (fp, tl, "", 1); |
| if (0) TI2_typlib_coclass_hdr (fp, tl, "", TKIND_COCLASS); |
| TI2_typlib_dispinterface_hdr (fp, tl, ""); |
| } |
| |
| void |
| TI2_typlib_idl (FILE *fp, sTI2TypLib *tl, const char *orgfname) |
| { |
| int befirst; |
| if (!tl) |
| return; |
| fprintf (fp, "/* Automated generated idl file <%s>.\n" |
| " * Generated by genidl tool (c) 2009-2016 Mingw-w64 project.\n" |
| " */\n\n", (tl->name ? tl->name : "unknown")); |
| |
| TI2_update_config (tl, orgfname); |
| TI2_typlib_forward_declare (fp, tl, 0); |
| TI2_typlib_enumerations (fp, tl, "", 0); |
| TI2_typlib_structures (fp, tl, "", 0); |
| TI2_typlib_typedefs (fp, tl, "", 0); |
| fprintf (fp, "[\n"); |
| befirst = 1; |
| if (tl->guid) |
| befirst = printUuid (fp, tl->guid, befirst, 0, ""); |
| if (tl->version != 0) |
| befirst = printVersion (fp, tl->version, befirst, 0, ""); |
| if (tl->helpstring) |
| befirst = printString (fp, "helpstring", tl->helpstring, befirst, 0, ""); |
| if (tl->helpfile) |
| befirst = printString (fp, "helpfile", tl->helpfile, befirst, 0, ""); |
| if (befirst != 1) |
| fprintf (fp, "\n"); |
| fprintf (fp, "]\n"); |
| fprintf (fp, "library %s\n{\n", tl->name); |
| TI2_typlib_imports (fp, tl, " "); |
| // coclass |
| TI2_typlib_coclass (fp, tl, " "); |
| // dispinterface |
| TI2_typlib_dispinterface (fp, tl, " "); |
| fprintf (fp, "};\n\n"); |
| TI2_typlib_interfaces (fp, tl, ""); |
| TI2_typlib_modules (fp, tl, ""); |
| } |