summaryrefslogtreecommitdiffstats
path: root/private/oleauto/tests/common/dispdbug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleauto/tests/common/dispdbug.cpp')
-rw-r--r--private/oleauto/tests/common/dispdbug.cpp890
1 files changed, 890 insertions, 0 deletions
diff --git a/private/oleauto/tests/common/dispdbug.cpp b/private/oleauto/tests/common/dispdbug.cpp
new file mode 100644
index 000000000..c3d606f73
--- /dev/null
+++ b/private/oleauto/tests/common/dispdbug.cpp
@@ -0,0 +1,890 @@
+/***
+*dispdbug.cpp
+*
+* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* Misc Debug utilities.
+*
+*Revision History:
+*
+* [00] 25-Sep-92 bradlo: Created.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "common.h"
+#include "dispdbug.h"
+
+LOCAL char *rgszVtFmt[] = {
+ "" // VT_EMPTY
+ , "" // VT_NULL
+ , "%d" // VT_I2
+ , "%ld" // VT_I4
+ , "%#f" // VT_R4
+ , "%#f" // VT_R8
+ , "%ld.%lu" // VT_CY
+ , "%#f" // VT_DATE
+#if HC_MPW
+ , "\"%s\"" // VT_BSTR
+#else
+ , "\"%Fs\"" // VT_BSTR
+#endif
+ , "" // VT_DISPATCH
+ , "0x%lX" // VT_ERROR
+ , "%d" // VT_BOOL
+ , NULL // VT_VARIANT - special format
+ , "" // VT_UNKNOWN
+ , "" // 14 is unused
+ , "" // 15 is unused
+ , "%d" // VT_I1
+ , "%ud" // VT_UI1
+};
+
+#if 0 /* Note: this is now supplied by the host test app */
+#ifndef _MAC
+
+extern "C" void
+DbPrintf(char FAR* szFormat, ...)
+{
+ va_list args;
+ char *pn, FAR* pf;
+static char rgchFmtBuf[512];
+static char rgchOutputBuf[1024];
+
+
+ // copy the 'far' format string to a near buffer so we can use
+ // the medium model vsprintf, which only supports near data pointers.
+ //
+ pn = rgchFmtBuf, pf=szFormat;
+ while(*pf != '\0')
+ *pn++ = *pf++;
+ *pn = '\0';
+
+ va_start(args, szFormat);
+ vsprintf(rgchOutputBuf, rgchFmtBuf, args);
+ OutputDebugString(rgchOutputBuf);
+}
+
+#endif
+#endif
+
+
+
+extern "C" void
+DbPrVt(VARTYPE vt)
+{
+ DbPrintf(DbSzOfVt(vt));
+}
+
+
+extern "C" char FAR*
+SzOfVarg(VARIANTARG FAR* pvarg)
+{
+ char *p;
+ short s;
+ VARTYPE vt;
+ void FAR* pv;
+ IUnknown FAR* punk;
+ IDispatch FAR* pdisp;
+
+static char buf[512];
+#if OE_WIN32
+ char buf2[256];
+#endif
+
+ if(pvarg == NULL)
+ return "(null)";
+
+ p = buf;
+
+ STRCPY(p, DbSzOfVt(V_VT(pvarg)));
+ p += strlen(p);
+
+ vt = V_VT(pvarg) & ~(VT_BYREF | VT_ARRAY);
+
+ pv = (V_ISBYREF(pvarg)) ? V_BYREF(pvarg) : &V_NONE(pvarg);
+
+ *p++ = '(';
+ *p = '\0';
+
+ switch(V_VT(pvarg)){
+ case VT_NULL:
+ case VT_EMPTY:
+ *p = '\0';
+ break;
+
+#if VBA2
+ case VT_UI1:
+ case VT_UI1 | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], (unsigned int)*(unsigned char FAR*)pv);
+ break;
+#endif //VBA2
+
+ case VT_I2:
+ case VT_I2 | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], *(short FAR*)pv);
+ break;
+
+ case VT_I4:
+ case VT_ERROR:
+ case VT_I4 | VT_BYREF:
+ case VT_ERROR | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], *(long FAR*)pv);
+ break;
+
+ case VT_R4:
+ case VT_R4 | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], (double)*(float FAR*)pv);
+ break;
+
+ case VT_CY:
+ case VT_CY | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], ((CY FAR*)pv)->Hi, ((CY FAR*)pv)->Lo);
+ break;
+
+ case VT_R8:
+ case VT_DATE:
+ case VT_R8 | VT_BYREF:
+ case VT_DATE | VT_BYREF:
+ sprintf(p, rgszVtFmt[vt], *(double FAR*)pv);
+ break;
+
+ case VT_BSTR:
+ case VT_BSTR | VT_BYREF:
+#if OE_WIN32
+ ConvertStrWtoA(*(BSTR FAR*)pv, buf2),
+ sprintf(p, rgszVtFmt[vt], buf2);
+#else
+ sprintf(p, rgszVtFmt[vt], *(BSTR FAR*)pv);
+#endif
+ break;
+
+ case VT_BOOL:
+ case VT_BOOL | VT_BYREF:
+ s = *(short FAR*)pv;
+ if(s == 0){
+ strcpy(p, "False(0)");
+ }else if(s == -1){
+ strcpy(p, "True(-1)");
+ }else{
+ *p++ = '?';
+ *p = '\0';
+ }
+ break;
+
+ case VT_UNKNOWN:
+ case VT_UNKNOWN | VT_BYREF:
+ punk = *(IUnknown FAR* FAR*)pv;
+ sprintf(p, rgszVtFmt[vt], punk);
+ break;
+
+ case VT_DISPATCH:
+ case VT_DISPATCH | VT_BYREF:
+ pdisp = *(IDispatch FAR* FAR*)pv;
+ sprintf(p, rgszVtFmt[vt], pdisp);
+ break;
+
+ case VT_VARIANT | VT_BYREF:
+ SzOfVarg(V_VARIANTREF(pvarg));
+ break;
+
+ default:
+ if(V_VT(pvarg) & VT_ARRAY){
+#if 0 /* Dont print addresses, makes the logfile un-diffable */
+ if(V_VT(pvarg) & VT_BYREF){
+ sprintf(p, "%lp", V_ARRAYREF(pvarg));
+ }else{
+ sprintf(p, "%lp", V_ARRAY(pvarg));
+ }
+#endif
+ }else{
+ *p++ = '?';
+ *p = '\0';
+ }
+ break;
+ }
+
+ p = buf + strlen(buf);
+
+ *p++ = ')';
+ *p = '\0';
+
+ return buf;
+}
+
+
+extern "C" void
+DbPrVarg(VARIANTARG FAR* pvarg)
+{
+ DbPrintf(SzOfVarg(pvarg));
+}
+
+
+/***
+*void DbPrData(void*, VARTYPE)
+*Purpose:
+* Print the given data according to the given VARTYPE.
+*
+*Entry:
+* vt = the VARTYPE of the data
+* pv = pointer to the data to print
+*
+*Exit:
+* None
+*
+***********************************************************************/
+extern "C" void
+DbPrData(void FAR* pv, VARTYPE vt)
+{
+#if OE_WIN32
+ char buf2[256];
+#endif
+ switch(vt){
+#if VBA2
+ case VT_UI1:
+ DbPrintf(rgszVtFmt[vt], (unsigned int)*(unsigned char FAR*)pv);
+ break;
+#endif //VBA2
+
+ case VT_I2:
+ case VT_BOOL:
+ DbPrintf(rgszVtFmt[vt], *(short FAR*)pv);
+ break;
+
+ case VT_I4:
+ case VT_ERROR:
+ DbPrintf(rgszVtFmt[vt], *(long FAR*)pv);
+ break;
+
+ case VT_R4:
+ DbPrintf(rgszVtFmt[vt], (double)*(float FAR*)pv);
+ break;
+
+ case VT_R8:
+ case VT_DATE:
+ DbPrintf(rgszVtFmt[vt], *(double FAR*)pv);
+ break;
+
+ case VT_CY:
+ DbPrintf(rgszVtFmt[vt], ((CY FAR*)pv)->Hi, ((CY FAR*)pv)->Lo);
+ break;
+
+ case VT_BSTR:
+#if OE_WIN32
+ ConvertStrWtoA(*(BSTR FAR*)pv, buf2),
+ DbPrintf(rgszVtFmt[vt], buf2);
+#else
+ DbPrintf(rgszVtFmt[vt], *(BSTR FAR*)pv);
+#endif
+ break;
+
+ case VT_VARIANT:
+ DbPrVarg((VARIANT FAR*)pv);
+ break;
+
+ case VT_UNKNOWN:
+ case VT_DISPATCH:
+ DbPrintf(rgszVtFmt[vt], *(IUnknown FAR* FAR*)pv);
+ break;
+
+#if OE_WIN32 && 0
+ case VT_WBSTR:
+ {
+ BSTR bstr;
+ bstr = SysStringWtoA(*(WBSTR FAR*)pv, CP_ACP);
+ DbPrintf(rgszVtFmt[vt], bstr);
+ SysFreeString(bstr);
+ break;
+ }
+
+ case VT_DISPATCHW:
+ DbPrintf(rgszVtFmt[vt], *(IUnknown FAR* FAR*)pv);
+ break;
+#endif
+
+ default:;
+ DbPrintf("?");
+ break;
+ }
+}
+
+
+/***
+*void DbPrExcepinfo(EXCEPINFO*)
+*Purpose:
+* Dump the given EXCEPINFO struct to the debug window.
+*
+*Entry:
+* pexcepinfo - the EXCEPINFO struct to dump
+*
+*Exit:
+* None
+*
+***********************************************************************/
+extern "C" void
+DbPrExcepinfo(EXCEPINFO FAR* pexcepinfo)
+{
+ DbPrintf("wCode=%d dwHelpContext=%ld\n",
+ pexcepinfo->wCode, pexcepinfo->dwHelpContext);
+
+#if HC_MPW
+ DbPrintf("bstrSource = \"%s\"\n", pexcepinfo->bstrSource);
+ DbPrintf("bstrDescription = \"%s\"\n", pexcepinfo->bstrDescription);
+ DbPrintf("bstrHelpFile = \"%s\"\n", pexcepinfo->bstrHelpFile);
+#else
+ DbPrintf("bstrSource = \"%Fs\"\n", pexcepinfo->bstrSource);
+ DbPrintf("bstrDescription = \"%Fs\"\n", pexcepinfo->bstrDescription);
+ DbPrintf("bstrHelpFile = \"%Fs\"\n", pexcepinfo->bstrHelpFile);
+#endif
+}
+
+#if OE_WIN32 && 0
+extern "C" void
+DbPrExcepinfoW(WEXCEPINFO FAR* pexcepinfo)
+{
+ BSTR source, description, helpFile;
+
+ source = SysStringWtoA(pexcepinfo->wbstrSource, CP_ACP);
+ description = SysStringWtoA(pexcepinfo->wbstrDescription, CP_ACP);
+ helpFile = SysStringWtoA(pexcepinfo->wbstrHelpFile, CP_ACP);
+
+ DbPrintf("wCode=%d dwHelpContext=%ld\n",
+ pexcepinfo->wCode, pexcepinfo->dwHelpContext);
+ DbPrintf("bstrSource = \"%Fs\"\n", source);
+ DbPrintf("bstrDescription = \"%Fs\"\n", description);
+ DbPrintf("bstrHelpFile = \"%Fs\"\n", helpFile);
+ SysFreeString(source);
+ SysFreeString(description);
+ SysFreeString(helpFile);
+}
+#endif
+
+/***
+*void DbPrParams(DISPPARAMS*)
+*Purpose:
+* Dump the given DISPPARAMS struct to the debug window.
+*
+*Entry:
+* pdispparams = the DISPPARAMS struct to dump.
+*
+*Exit:
+* None
+*
+***********************************************************************/
+extern "C" void
+DbPrParams(DISPPARAMS FAR* pdispparams)
+{
+ unsigned int i;
+
+ DbPrintf("cArgs = %d\n", pdispparams->cArgs);
+ DbPrintf("rgvarg = [");
+ for(i = 0; i < pdispparams->cArgs; ++i){
+ DbPrVarg(&pdispparams->rgvarg[i]);
+ if(i+1 < pdispparams->cArgs)
+ DbPrintf(", ");
+ }
+ DbPrintf("]\n");
+
+ DbPrintf("cNamedArgs = %d\n", pdispparams->cNamedArgs);
+ DbPrintf("rgdispidNamedArgs = [");
+ for(i = 0; i < pdispparams->cNamedArgs; ++i){
+ DbPrintf("%ld", pdispparams->rgdispidNamedArgs[i]);
+ if(i+1 < pdispparams->cNamedArgs)
+ DbPrintf(", ");
+ }
+ DbPrintf("]\n");
+}
+
+
+void
+PrScode(SCODE sc)
+{
+#if HC_MPW
+ DbPrintf("[%s]", DbSzOfScode(sc));
+#else
+ DbPrintf("[%Fs]", DbSzOfScode(sc));
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// TypeInfo dumping utilities
+//---------------------------------------------------------------------
+
+/* naming convention:
+ *
+ * Pr<type> - dump the type with cr/lf
+ * Pr<type>N - dump type without cr/lf
+ * Pr<type>X - dump type with given indent level
+ *
+ */
+
+void
+DbIndent(int level)
+{
+ for(int i = 0; i < level; ++i)
+ DbPrintf(" ");
+}
+
+void
+PrGuidN(GUID FAR* pguid)
+{
+ DbPrintf("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ pguid->Data1, pguid->Data2, pguid->Data3,
+ pguid->Data4[0], pguid->Data4[1], pguid->Data4[2], pguid->Data4[3],
+ pguid->Data4[4], pguid->Data4[5], pguid->Data4[6], pguid->Data4[7]);
+}
+
+void
+PrGuid(GUID FAR* pguid)
+{
+ PrGuidN(pguid);
+ DbPrintf("\n");
+}
+
+void
+PrTypekindN(TYPEKIND tkind)
+{
+ switch(tkind){
+ case TKIND_ENUM:
+ DbPrintf("TKIND_ENUM");
+ break;
+ case TKIND_RECORD:
+ DbPrintf("TKIND_RECORD");
+ break;
+ case TKIND_MODULE:
+ DbPrintf("TKIND_MODULE");
+ break;
+ case TKIND_INTERFACE:
+ DbPrintf("TKIND_INTERFACE");
+ break;
+ case TKIND_DISPATCH:
+ DbPrintf("TKIND_DISPATCH");
+ break;
+ case TKIND_COCLASS:
+ DbPrintf("TKIND_COCLASS");
+ break;
+ case TKIND_ALIAS:
+ DbPrintf("TKIND_ALIAS");
+ break;
+ case TKIND_UNION:
+ DbPrintf("TKIND_UNION");
+ break;
+ default:
+ DbPrintf("UNKNOWN");
+ break;
+ }
+}
+
+void PrVarkindN(VARKIND vkind)
+{
+ switch(vkind){
+ case VAR_PERINSTANCE:
+ DbPrintf("VAR_PERINSTANCE");
+ break;
+ case VAR_STATIC:
+ DbPrintf("VAR_STATIC");
+ break;
+ case VAR_CONST:
+ DbPrintf("VAR_CONST");
+ break;
+ case VAR_DISPATCH:
+ DbPrintf("VAR_DISPATCH");
+ break;
+ default:
+ DbPrintf("UNKNOWN");
+ }
+}
+
+void
+PrFunckindN(FUNCKIND fkind)
+{
+ switch(fkind){
+ case FUNC_VIRTUAL:
+ DbPrintf("FUNC_VIRTUAL");
+ break;
+ case FUNC_PUREVIRTUAL:
+ DbPrintf("FUNC_PUREVIRTUAL");
+ break;
+ case FUNC_NONVIRTUAL:
+ DbPrintf("FUNC_NONVIRTUAL");
+ break;
+ case FUNC_STATIC:
+ DbPrintf("FUNC_STATIC");
+ break;
+ case FUNC_DISPATCH:
+ DbPrintf("FUNC_DISPATCH");
+ break;
+ default:
+ DbPrintf("UNKNOWN");
+ }
+}
+
+void
+PrInvokekindN(INVOKEKIND invkind)
+{
+ switch(invkind){
+ case INVOKE_FUNC:
+ DbPrintf("INVOKE_FUNC");
+ break;
+ case INVOKE_PROPERTYGET:
+ DbPrintf("INVOKE_PROPERTYGET");
+ break;
+ case INVOKE_PROPERTYPUT:
+ DbPrintf("INVOKE_PROPERTYPUT");
+ break;
+ case INVOKE_PROPERTYPUTREF:
+ DbPrintf("INVOKE_PROPERTYPUTREF");
+ break;
+ default:
+ DbPrintf("UNKNOWN");
+ break;
+ }
+}
+
+void
+PrCallconvN(CALLCONV cc)
+{
+ switch(cc){
+ case CC_CDECL:
+ DbPrintf("CC_CDECL");
+ break;
+ case CC_MSCPASCAL:
+ DbPrintf("CC_MSCPASCAL");
+ break;
+ case CC_MACPASCAL:
+ DbPrintf("CC_MACPASCAL");
+ break;
+ case CC_STDCALL:
+ DbPrintf("CC_STDCALL");
+ break;
+ case CC_RESERVED:
+ DbPrintf("CC_RESERVED");
+ break;
+ default:
+ DbPrintf("UNKNOWN");
+ break;
+ }
+}
+
+void
+PrTypeFlagsN(unsigned short wTypeFlags)
+{
+ DbPrintf("[");
+ if(wTypeFlags & TYPEFLAG_FAPPOBJECT)
+ DbPrintf("AppObject");
+ DbPrintf("]");
+}
+
+void
+PrFuncFlagsN(unsigned short wFuncFlags)
+{
+ DbPrintf("[");
+ if(wFuncFlags & FUNCFLAG_FRESTRICTED)
+ DbPrintf("Restricted");
+ DbPrintf("]");
+}
+
+void
+PrTypedescN(TYPEDESC FAR* ptdesc)
+{
+ DbPrVt(ptdesc->vt);
+
+ switch(ptdesc->vt){
+#if 0 /* REVIEW: NYI */
+ case VT_CARRAY:
+ DbPrintf(" ");
+ PrAdesc(ptdesc->lpadesc);
+ break;
+#endif
+ case VT_PTR:
+ DbPrintf(" ");
+ PrTypedescN(ptdesc->lptdesc);
+ break;
+ case VT_USERDEFINED:
+ DbPrintf(" hreftype=%d", (int)ptdesc->hreftype);
+ break;
+#if 0 /* obsolete */
+ case VT_FIXEDSTRING:
+ DbPrintf(" cbSize=%d", (int)ptdesc->cbSize);
+ break;
+#endif
+ }
+}
+
+void
+PrTdesc(TYPEDESC FAR* ptdesc)
+{
+ PrTypedescN(ptdesc);
+ DbPrintf("\n");
+}
+
+// print the given TYPEATTR
+void
+PrTypeattrXN(TYPEATTR FAR* ptattr, int level)
+{
+ PrTypekindN(ptattr->typekind);
+
+ DbPrintf(" ");
+ PrGuidN(&ptattr->guid);
+
+ DbPrintf("\n");
+ DbIndent(level);
+ DbPrintf("ver=%d.%d lcid=0x%lx",
+ (int)ptattr->wMajorVerNum,
+ (int)ptattr->wMinorVerNum,
+ ptattr->lcid);
+
+ DbPrintf(" cFunc=%d cVar=%d cImpl=%d cbAlign=%d cbInst=%d cbVft=%d",
+ (int)ptattr->cFuncs,
+ (int)ptattr->cVars,
+ (int)ptattr->cImplTypes,
+ (int)ptattr->cbAlignment,
+ (int)ptattr->cbSizeInstance,
+ (int)ptattr->cbSizeVft);
+
+#if 0 /* REVIEW: add support for the following */
+ ptattr->idldescType
+ ptattr->memidConstructor
+ ptattr->memidDestructor
+#endif
+
+ if(ptattr->typekind == TKIND_ALIAS){
+ DbPrintf(" alias=");
+ PrTypedescN(&ptattr->tdescAlias);
+ }
+
+ DbPrintf(" ");
+ PrTypeFlagsN(ptattr->wTypeFlags);
+}
+
+void
+PrTypeattrX(TYPEATTR FAR* ptattr, int level)
+{
+ PrTypeattrXN(ptattr, level);
+ DbPrintf("\n");
+}
+
+void
+PrIdldescN(IDLDESC FAR* pidldesc)
+{
+ UNUSED(pidldesc);
+ // REVIEW: NYI
+}
+
+void
+PrElemdescN(ELEMDESC FAR* pelemdesc)
+{
+ PrTypedescN(&pelemdesc->tdesc);
+#if 0 /* REVIEW: NYI */
+ DbPrintf(" ");
+ PrIdldescN(&pelemdesc->idldesc);
+#endif
+}
+
+void
+PrVardescXN(VARDESC FAR* pvdesc, int level)
+{
+ UNUSED(level);
+
+ DbPrintf("ID(0x%lx) ", (long)pvdesc->memid);
+ PrVarkindN(pvdesc->varkind);
+ DbPrintf(" ");
+ PrElemdescN(&pvdesc->elemdescVar);
+ switch(pvdesc->varkind){
+ case VAR_PERINSTANCE:
+ DbPrintf("oInst=%lu", pvdesc->oInst);
+ break;
+ case VAR_CONST:
+ DbPrintf("value=%Fs", SzOfVarg(pvdesc->lpvarValue));
+ break;
+ case VAR_STATIC:
+ case VAR_DISPATCH:
+ break;
+ }
+}
+
+void
+PrFuncdescXN(FUNCDESC FAR* pfdesc, int level)
+{
+ int i;
+
+ PrFunckindN(pfdesc->funckind);
+
+ DbPrintf(" ID(%ld)", pfdesc->memid);
+
+ DbPrintf(" ");
+ PrInvokekindN(pfdesc->invkind);
+
+ DbPrintf(" ");
+ PrCallconvN(pfdesc->callconv);
+
+ DbPrintf(" oVft=%d", (int)pfdesc->oVft);
+
+ DbPrintf(" cParam=%d(%d)",
+ (int)pfdesc->cParams, (int)pfdesc->cParamsOpt);
+
+ DbPrintf(" ");
+ PrFuncFlagsN(pfdesc->wFuncFlags);
+
+ DbPrintf("\n");
+ DbIndent(level);
+
+ PrElemdescN(&pfdesc->elemdescFunc);
+
+ DbPrintf(" (");
+ if(pfdesc->cParams > 0){
+ for(i = 0;;){
+ PrElemdescN(&pfdesc->lprgelemdescParam[i]);
+ if(++i >= pfdesc->cParams)
+ break;
+ DbPrintf(", ");
+ }
+ }
+ DbPrintf(")");
+}
+
+// helper for PrTi()
+LOCAL HRESULT
+PrMembersX(
+ ITypeInfo FAR* ptinfo,
+ TYPEATTR FAR* ptattr,
+ int fFuncs,
+ int level)
+{
+ int i, num;
+ MEMBERID memid;
+ VARDESC FAR* pvdesc;
+ FUNCDESC FAR* pfdesc;
+ unsigned long dwHelpContext;
+ BSTR bstrName, bstrDoc, bstrHelpFile;
+#if OE_WIN32
+ char buf[256], buf2[256];
+#endif
+ num = fFuncs ? ptattr->cFuncs : ptattr->cVars;
+
+ for(i = 0; i < num; ++i){
+ if(fFuncs){
+ IfFailRet(ptinfo->GetFuncDesc(i, &pfdesc));
+ memid = pfdesc->memid;
+ }else{
+ IfFailRet(ptinfo->GetVarDesc(i, &pvdesc));
+ memid = pvdesc->memid;
+ }
+
+ IfFailRet(ptinfo->GetDocumentation(
+ memid, &bstrName, &bstrDoc, &dwHelpContext, &bstrHelpFile));
+
+ DbIndent(level);
+ DbPrintf("- ");
+ if(fFuncs){
+ PrFuncdescXN(pfdesc, level+2);
+ ptinfo->ReleaseFuncDesc(pfdesc);
+ }else{
+ PrVardescXN(pvdesc, level+2);
+ ptinfo->ReleaseVarDesc(pvdesc);
+ }
+
+ DbPrintf("\n");
+ DbIndent(level+2);
+#if OE_WIN32
+ ConvertStrWtoA(bstrName, buf);
+ DbPrintf("\"%Fs\"", buf);
+#else
+ DbPrintf("\"%Fs\"", bstrName);
+#endif
+
+ DbPrintf(" Doc=\"%Fs\" HelpFile=\"%Fs\" HelpContext=%ld\n",
+#if OE_WIN32
+ bstrDoc == NULL ? "" : ConvertStrWtoA(bstrDoc, buf),
+ bstrHelpFile == NULL ? "" : ConvertStrWtoA(bstrHelpFile, buf2),
+ dwHelpContext);
+#else
+ bstrDoc == NULL ? "" : bstrDoc,
+ bstrHelpFile == NULL ? "" : bstrHelpFile,
+ dwHelpContext);
+#endif
+
+ SysFreeString(bstrName);
+ SysFreeString(bstrDoc);
+ SysFreeString(bstrHelpFile);
+ }
+
+ return NOERROR;
+}
+
+void
+PrTiX(ITypeInfo FAR* ptinfo, int level)
+{
+ int i;
+ HRESULT hresult;
+ HREFTYPE hreftype;
+ TYPEATTR FAR* ptattr;
+ ITypeInfo FAR* ptinfoRef;
+
+
+ // indent based on the given level
+ DbIndent(level);
+
+ DbPrintf("[ ");
+
+ IfFailGo(ptinfo->GetTypeAttr(&ptattr), LError0);
+
+ PrTypeattrX(ptattr, level+2);
+
+ // dump the variables, if any
+ if(ptattr->cVars != 0){
+ IfFailGo(PrMembersX(ptinfo, ptattr, FALSE, level+2), LError1);
+ }
+
+ // dump the functions, if any
+ if(ptattr->cFuncs != 0){
+ IfFailGo(PrMembersX(ptinfo, ptattr, TRUE, level+2), LError1);
+ }
+
+ // dump the referenced type infos, if any
+ if(ptattr->cImplTypes != 0){
+ for(i = 0; i < (int)ptattr->cImplTypes; ++i){
+ if((hresult = ptinfo->GetRefTypeOfImplType(i, &hreftype)) != NOERROR){
+ PrScode(GetScode(hresult));
+ break;
+ }
+ if((hresult = ptinfo->GetRefTypeInfo(hreftype, &ptinfoRef)) != NOERROR){
+ PrScode(GetScode(hresult));
+ break;
+ }
+ PrTiX(ptinfoRef, level+6);
+ ptinfoRef->Release();
+ }
+ }
+
+ DbIndent(level);
+ DbPrintf("]");
+
+LError1:;
+ ptinfo->ReleaseTypeAttr(ptattr);
+
+LError0:;
+ DbPrintf("\n");
+
+ if(hresult != NOERROR){
+ DbPrintf("ERROR: ");
+ PrScode(GetScode(hresult));
+ DbPrintf("\n");
+ }
+}
+
+// print the given TypeInfo
+void
+PrTi(ITypeInfo FAR* ptinfo)
+{
+ PrTiX(ptinfo, 0);
+}