diff options
Diffstat (limited to 'private/oleauto/src/mktyplib/hout.c')
-rw-r--r-- | private/oleauto/src/mktyplib/hout.c | 1111 |
1 files changed, 1111 insertions, 0 deletions
diff --git a/private/oleauto/src/mktyplib/hout.c b/private/oleauto/src/mktyplib/hout.c new file mode 100644 index 000000000..32b7594ab --- /dev/null +++ b/private/oleauto/src/mktyplib/hout.c @@ -0,0 +1,1111 @@ +#include "mktyplib.h" + +// .H file output for MKTYPLIB + +#include <stdio.h> + +#ifndef WIN32 +#include <ole2.h> // required for dispatch.h +#include "dispatch.h" +#endif //WIN32 + +#include "errors.h" +#include "fileinfo.h" +#include "intlstr.h" // for szHead* definitions + +// external data +extern TYPLIB typlib; +extern FILE *hHFile; +extern SYSKIND SysKind; +extern int iAlignMax; +extern int iAlignDef; +extern BOOL fSpecifiedInterCC; + + +// external functions +extern INT FAR FCmpCaseIns(LPSTR str1, LPSTR str2); + + +// private data +static CHAR *szHeadOlePrefix0 = "#undef INTERFACE\n" + "#define INTERFACE "; +static CHAR *szHeadOlePrefix1 = "DECLARE_INTERFACE"; +static CHAR *szHeadOlePrefix2 = ")\n{\n"; +static CHAR *szHeadOlePrefix3 = "\n /* "; +static CHAR *szHeadOlePrefix4 = " methods */\n"; +static CHAR *szHeadOlePrefix5 = " properties:\n"; +static CHAR *szHeadOlePrefix6 = " methods:\n"; +static CHAR *szHeadOlePrefix7 = "#ifndef NO_BASEINTERFACE_FUNCS\n"; +static CHAR *szHeadOleFuncPrefix1 = " "; // leading spaces +static CHAR *szHeadOleFuncPrefix2 = "STDMETHOD"; +static CHAR *szHeadOleFuncPrefix3 = ", "; // after return type +static CHAR *szHeadOleArgPrefix1 = ")(THIS"; +static CHAR *szHeadOleArgPrefix2 = "_ "; // only if args +static CHAR *szHeadOleArgSuffix = ") PURE;\n"; +static CHAR *szHeadOleSuffix1 = " */\n"; +static CHAR *szHeadOleSuffix2 = "};\n"; +static CHAR *szHeadOleSuffix3 = " */\n"; +static CHAR *szHeadOleSuffix7 = "#endif\n"; + +//Hack for profiling +//#define PROFILE + +#ifdef PROFILE +static unsigned long cFuncsTotal = 0; +static unsigned long cArgsTotal = 0; +static unsigned long cVarsTotal = 0; +#endif //PROFILE + +// stuff dealing with non-default interface calling conventions +static CHAR *szUndefCallType = "#undef STDMETHODCALLTYPE\n"; +static CHAR *szResetCallType = +"#if defined(WIN32)\n" +"#define STDMETHODCALLTYPE STDMETHODSTDCALL\n" +"#else\n" +"#define STDMETHODCALLTYPE STDMETHODCDECL\n" +"#endif\n"; + +static CHAR *szDefCallTypePrefix = "#define STDMETHODCALLTYPE STDMETHOD"; + +static CHAR *rgszCallType[] = { + "CDECL", + "PASCAL", + "STDCALL" +}; + +typedef enum { + CALL_CDECL, + CALL_PASCAL, + CALL_STDCALL, + CALL_DEFAULT +} CALLINGCONV; + +static CALLINGCONV ccInterCurrent = CALL_DEFAULT; + +// user-specified calling conventions for all platforms +static CHAR * szCCHeader = +"\n" +"/* Macros for redefining the STDMETHOD calling convention\n" +" * (STDMETHODCALLTYPE).\n" +" */\n" +"\n" +"#if defined(_MAC)\n" +"\n" +"#if !defined(_MSC_VER)\n" +"#define STDMETHODCDECL\n" +"#define STDMETHODPASCAL\n" +"#define STDMETHODSTDCALL\n" +"#else\n" +"#define STDMETHODCDECL FAR CDECL\n" +"#define STDMETHODPASCAL FAR PASCAL\n" +"#define STDMETHODSTDCALL FAR STDCALL\n" +"#endif\n" +"\n" +"#elif defined(WIN32)\n" +"\n" +"#define STDMETHODCDECL EXPORT __cdecl\n" +"#define STDMETHODPASCAL EXPORT __pascal\n" +"#define STDMETHODSTDCALL EXPORT __stdcall\n" +"\n" +"#else /* WIN16 */\n" +"\n" +"#define STDMETHODCDECL __export FAR CDECL\n" +"#define STDMETHODPASCAL __export FAR PASCAL\n" +"#define STDMETHODSTDCALL __export FAR STDCALL\n" +"\n" +"#endif\n" +"\n"; + + +// canned definition of IUnknown +static CHAR * szHeadIUnknown = +"\n" +" /* IUnknown methods */\n" +" STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;\n" +" STDMETHOD_(ULONG, AddRef)(THIS) PURE;\n" +" STDMETHOD_(ULONG, Release)(THIS) PURE;\n"; + +// canned definition of IDispatch +static CHAR * szHeadIDispatch = +"\n" +" /* IDispatch methods */\n" +" STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo) PURE;\n" +"\n" +" STDMETHOD(GetTypeInfo)(\n" +" THIS_\n" +" UINT itinfo,\n" +" LCID lcid,\n" +" ITypeInfo FAR* FAR* pptinfo) PURE;\n" +"\n" +" STDMETHOD(GetIDsOfNames)(\n" +" THIS_\n" +" REFIID riid,\n" +" OLECHAR FAR* FAR* rgszNames,\n" +" UINT cNames,\n" +" LCID lcid,\n" +" DISPID FAR* rgdispid) PURE;\n" +"\n" +" STDMETHOD(Invoke)(\n" +" THIS_\n" +" DISPID dispidMember,\n" +" REFIID riid,\n" +" LCID lcid,\n" +" WORD wFlags,\n" +" DISPPARAMS FAR* pdispparams,\n" +" VARIANT FAR* pvarResult,\n" +" EXCEPINFO FAR* pexcepinfo,\n" +" UINT FAR* puArgErr) PURE;\n"; + +static CHAR *szHeadGuidPrefix = "\nDEFINE_GUID("; +static CHAR *szHeadGuidLIBID = "LIBID_"; +static CHAR *szHeadGuidCLSID = "CLSID_"; +static CHAR *szHeadGuidIID = "IID_"; +static CHAR *szHeadGuidDIID = "DIID_"; + +// prototypes +VOID FAR OutputHFile (CHAR * szHFile); +VOID NEAR HOutTypedef(LPTYPE pType); +VOID NEAR HOutEnum(LPTYPE pType); +VOID NEAR HOutStructUnion(LPTYPE pType); +VOID NEAR HOutModule(LPENTRY pEntry); +VOID NEAR HOutInterface(LPENTRY pEntry); +VOID NEAR HOutCoclass(LPENTRY pEntry); +VOID NEAR HOutBaseInter(LPENTRY pEntry, BOOL fRecurse); + +VOID NEAR HOutFuncs(LPFUNC pFuncList, TENTRYKIND tentryKind); +VOID NEAR HOutElems(LPELEM pElemList, CHAR * szPrefix, CHAR * szSep, CHAR * szSepLast, BOOL fEnum); +VOID NEAR HOutType(LPTYPE pType); +VOID NEAR HOutShortNum(SHORT num, BOOL fHex); +VOID NEAR HOutLongNum(LONG num, BOOL fHex); +VOID NEAR HOutPropPrefix(LPFUNC pFunc); +VOID NEAR HOutGuid(LPATTR pAttr, CHAR * szGuidPrefix, LPSTR lpszName); + +#ifdef PROFILE +VOID NEAR XOutF(LPSTR lpszData); +VOID NEAR XOut(CHAR * szData); +#else //PROFILE +#define XOutF HOutF +#define XOut HOut +#endif //PROFILE +VOID NEAR HOutF(LPSTR lpszData); +VOID NEAR HOut(CHAR * szData); +VOID NEAR SetCallType(CALLINGCONV cc); + + +VOID FAR OutputHFile +( + CHAR * szHFile +) +{ + LPENTRY pEntry; + +#ifdef WIN16 + // convert szHFile in-place to OEM char set + AnsiToOem(szHFile, szHFile); + + // don't bother converting back since this string is not used again +#endif // WIN16 + + // open the file + hHFile = fopen(szHFile, "w"); // open output file + if (hHFile == NULL) + ParseError(ERR_CANT_OPEN_HFILE); + + Assert (SYS_WIN16 == 0 && SYS_WIN32 == 1 && SYS_MAC == 2 && SysKind <= SYS_MAX); + + HOut(szHeadFile); // output file header + HOutF(typlib.szLibName); // output type library name + HOut(" */\n\n#ifndef _"); // output: #ifndef _<libname>_H_ + HOutF(typlib.szLibName); // #define _<libname>_H_ + HOut("_H_\n#define _"); + HOutF(typlib.szLibName); + HOut("_H_\n"); + + HOutGuid(&typlib.attr, szHeadGuidLIBID, typlib.szLibName); + + if (fSpecifiedInterCC) { + HOut(szCCHeader); + } + + if (typlib.pEntry) + { + pEntry = (LPENTRY)ListFirst(typlib.pEntry); // point to first entry + +#pragma warning(disable:4127) + while (TRUE) +#pragma warning(default:4127) + { + + switch (pEntry->type.tentrykind & ~tFORWARD) + { + case tTYPEDEF: + HOutTypedef(&pEntry->type); + break; + + case tENUM: + HOutEnum(&pEntry->type); + break; + + case tSTRUCT: + case tUNION: + HOutStructUnion(&pEntry->type); + break; + + case tMODULE: + HOutModule(pEntry); + break; + + case tCOCLASS: + HOutCoclass(pEntry); + break; + + case tINTERFACE: + case tDISPINTER: + HOutInterface(pEntry); + // fall through + + case tINTRINSIC: + case tREF: + break; // nothing to output + +#ifdef DEBUG + default: + if (pEntry->type.tentrykind & tIMPORTED) + break; // noting to output for imported types + Assert(FALSE); +#endif //DEBUG + } + + // advance to next entry if not all done + if (pEntry == (LPENTRY)ListLast(typlib.pEntry)) + break; // exit if all done + pEntry = (LPENTRY)pEntry->type.pNext; + + } // WHILE + } + + HOut("\n#endif\n"); + + fclose(hHFile); // done writing .H file + hHFile = NULL; // close done + + // check for possible alignment problems + if (iAlignMax != iAlignDef) + ParseError(WARN_STRANGE_ALIGNMENT); + +#ifdef PROFILE + printf("\n\ntotal functions: %d\n", cFuncsTotal); + printf("total function args: %d\n", cArgsTotal); + printf("total variables: %d\n", cVarsTotal); + ParseError(ERR_OM); // bogus early quit +#endif //PROFILE + +} + + +VOID NEAR HOutTypedef +( +LPTYPE pType +) +{ + XOut("\ntypedef "); + + // output base type + HOutType(pType->td.ptypeAlias); + HOut(" "); + + XOutF(pType->szName); + + Assert(pType->td.ptypeAlias->tdesc.vt != VT_CARRAY); + + XOut(";\n"); + +} + + +VOID NEAR HOutEnum +( +LPTYPE pType +) +{ + + XOut("\ntypedef enum "); + + if (pType->structenum.szTag) + { + XOutF(pType->structenum.szTag); + if (pType->tentrykind & tFORWARD) + { + XOut(";\n"); + return; + } + XOut(" "); + } + + XOut("{\n"); + + HOutElems(pType->structenum.elemList, " ", ",\n", "\n", TRUE); + + XOut("} "); + XOutF(pType->szName); + XOut(";\n"); + +} + +VOID NEAR HOutStructUnion +( +LPTYPE pType +) +{ + + if ((pType->tentrykind & ~tFORWARD) == tSTRUCT) + XOut("\ntypedef struct "); + else + XOut("\ntypedef union "); + + if (pType->structenum.szTag) + { + XOutF(pType->structenum.szTag); + if (pType->tentrykind & tFORWARD) + goto done; + + XOut(" "); + } + + XOut("{\n"); + + HOutElems(pType->structenum.elemList, " ", ";\n", ";\n", FALSE); + + XOut("} "); + XOutF(pType->szName); + +done: + XOut(";\n"); + +} + +VOID NEAR HOutModule +( +LPENTRY pEntry +) +{ + XOut(szHeadModule); + XOutF(pEntry->type.szName); + XOut(szHeadOleSuffix3); + HOutFuncs(pEntry->module.funcList, pEntry->type.tentrykind); + if (pEntry->module.constList) + HOutElems(pEntry->module.constList, " const ", ";\n", ";\n", FALSE); + +} + +VOID NEAR HOutCoclass +( +LPENTRY pEntry +) +{ + if ((pEntry->type.tentrykind & tFORWARD) == 0) { + HOutGuid(&pEntry->attr, szHeadGuidCLSID, pEntry->type.szName); + } + + // UNDONE: I don't think this will work in C. + + HOut("\n#ifdef __cplusplus\nclass "); + HOutF(pEntry->type.szName); + HOut(";\n#endif\n"); + +} + + +VOID NEAR HOutInterface +( +LPENTRY pEntry +) +{ + +LPSTR lpszBaseName; +TENTRYKIND tentrykind; +LPINTER lpInterFirst; // first base interface, if any +LPINTER lpInterLast; // second/last base interface, if any + + tentrykind = pEntry->type.tentrykind; + + if (tentrykind & tFORWARD) + { + // UNDONE: proper OLE format for forward declaration of interface? + // UNDONE: I don't think this will work in C. I think it wants: + // UNDONE: typedef interface <interfacename> <interfacename>; + HOut("\ninterface "); + HOutF(pEntry->type.szName); + HOut(";\n"); + return; + } + + HOutGuid(&pEntry->attr, + ((tentrykind == tDISPINTER) ? szHeadGuidDIID: szHeadGuidIID), + pEntry->type.szName); + + lpszBaseName = NULL; + lpInterFirst = NULL; + if (pEntry->type.inter.interList) + { + lpInterFirst = (LPINTER)ListFirst(pEntry->type.inter.interList); + lpInterLast = (LPINTER)ListLast(pEntry->type.inter.interList); + + // We assume there's only single inheritance at this point + // But in the case of a dispinterface, we could have the first + // base interface be IDispatch, and the 2nd base interface be + // the interface that we're capable of dispatching on. In any + // case, there can't be more than 2 interfaces in the list. + Assert((LPINTER)lpInterFirst->pNext == lpInterLast); + + lpszBaseName = lpInterFirst->ptypeInter->szName; + Assert(lpszBaseName); + } + + // first output the header comment + HOut((tentrykind == tDISPINTER) ? szHeadDispinter: szHeadInter); + HOutF(pEntry->type.szName); + HOut(szHeadOleSuffix3); + + // then output the OLE header + HOut(szHeadOlePrefix0); + HOutF(pEntry->type.szName); + HOut("\n\n"); + + HOut(szHeadOlePrefix1); + if (lpszBaseName) + HOut("_"); + HOut("("); + HOutF(pEntry->type.szName); + if (lpszBaseName) // if this inherits from somebody + { // then add ", <baseinterface>" + HOut(", "); + HOutF(lpszBaseName); + } + HOut(szHeadOlePrefix2); + + if (tentrykind == tDISPINTER) + { + Assert (lpszBaseName); + + HOut(szHeadOlePrefix7); + HOut(szHeadIUnknown); + HOut(szHeadIDispatch); + HOut(szHeadOleSuffix7); + + if (lpInterFirst != lpInterLast) + { // specifies an interface that is dispatchable + HOut(szHeadDispatchable); + HOutF(lpInterLast->ptypeInter->szName); + HOut(szHeadOleSuffix3); + } + + // first output the properties (commented out) in "struct" format + if (pEntry->dispinter.propList) + { + XOut(szHeadOlePrefix3); + XOutF(pEntry->type.szName); + XOut(szHeadOlePrefix5); + HOutElems(pEntry->dispinter.propList, " ", ";\n", ";\n", FALSE); + HOut(szHeadOleSuffix1); + } + + // then output the methods (commented out) in "normal" format + if (pEntry->dispinter.methList) + { + XOut(szHeadOlePrefix3); + XOutF(pEntry->type.szName); + XOut(szHeadOlePrefix6); + HOutFuncs(pEntry->dispinter.methList, tDISPINTER); + HOut(szHeadOleSuffix1); + } + } + else + { // an interface + + // output interface functions, and base interface functions (if any) + HOutBaseInter(pEntry, FALSE); + + } + + // lastly, output the close curly + HOut(szHeadOleSuffix2); + +} + + +VOID NEAR HOutBaseInter(LPENTRY pEntry, BOOL fRecurse) +{ + LPINTER lpInterBase; + + // hard-coded descriptions for the 2 most common + if (!FCmpCaseIns(pEntry->type.szName, "IUnknown")) + { + HOut(szHeadIUnknown); + } + else if (!FCmpCaseIns(pEntry->type.szName, "IDispatch")) + { + if (!fRecurse) + HOut(szHeadOlePrefix7); + HOut(szHeadIUnknown); + if (!fRecurse) + HOut(szHeadOleSuffix7); + + HOut(szHeadIDispatch); + } + else if ((pEntry->type.tentrykind & ~tFORWARD) != tINTERFACE) + { + // can't deal with imported base interfaces + HOut(szHeadOlePrefix3); + HOutF(pEntry->type.szName); + HOut(szHeadOlePrefix4); + HOut(szHeadMethods); + } + else + { + if (pEntry->type.tentrykind & tFORWARD) { + // if this is a forward decl, follow pointer back to real + // interface (since base interfaces and functions aren't + // stored in the forward declare) + pEntry = pEntry->lpEntryForward; + } + + lpInterBase = pEntry->type.inter.interList; + if (lpInterBase) // if this inherits from somebody, + { // then first describe the base interface + if (!fRecurse) + HOut(szHeadOlePrefix7); + + // HACK -- assumes we can cast LPTYPE to LPENTRY, but + // this is always true given our above validation + HOutBaseInter((LPENTRY)(lpInterBase->ptypeInter), TRUE); + + if (!fRecurse) + HOut(szHeadOleSuffix7); + } + + // output the interface functions in OLE format + XOut(szHeadOlePrefix3); + XOutF(pEntry->type.szName); + XOut(szHeadOlePrefix4); + HOutFuncs(pEntry->inter.funcList, tINTERFACE); + } +} + +//*********************************************************************** + +VOID NEAR HOutFuncs +( + LPFUNC pFuncList, + TENTRYKIND tentryKind +) +{ + + LPFUNC pFunc; + + if (pFuncList == NULL) // nothing to output if no functions + return; + + pFunc = (LPFUNC)ListFirst(pFuncList); // point to first entry + +#pragma warning(disable:4127) + while (TRUE) +#pragma warning(default:4127) + { + +#ifndef PROFILE + if (tentryKind == tINTERFACE) + { + if (fSpecifiedInterCC) { + // set up STDMETHODCALLTYPE based on the calling + // convention and SYSKIND + + if (pFunc->func.attr.fAttr2 & f2CCDEFAULTED) + SetCallType(CALL_DEFAULT); + else if (pFunc->func.attr.fAttr2 & f2PASCAL) + SetCallType(CALL_PASCAL); + else if (pFunc->func.attr.fAttr2 & f2STDCALL) + SetCallType(CALL_STDCALL); + else + { + Assert(pFunc->func.attr.fAttr2 & f2CDECL) + SetCallType(CALL_CDECL); + } + } + + + HOut(szHeadOleFuncPrefix1); // leading spaces + HOut(szHeadOleFuncPrefix2); + + if (pFunc->func.elemType->tdesc.vt == VT_HRESULT) + HOut("("); + else + { + HOut("_("); + // output function return type + HOutType(pFunc->func.elemType); + HOut(szHeadOleFuncPrefix3); + } + + HOutPropPrefix(pFunc); + XOutF(pFunc->func.szElemName); + + HOut(szHeadOleArgPrefix1); + + if (pFunc->cArgs) + { + HOut(szHeadOleArgPrefix2); + // output list of variables, separating them by + // commas, with nothing after last item + HOutElems(pFunc->argList, "", ", ", "", FALSE); + } + XOut(szHeadOleArgSuffix); + } + else +#endif //!PROFILE + { + HOut(szHeadOleFuncPrefix1); // leading spaces + if (tentryKind == tMODULE) + HOut ("extern "); + + // output function return type + HOutType(pFunc->func.elemType); + HOut(" "); + + // output calling convention + if (!(pFunc->func.attr.fAttr2 & f2CCDEFAULTED)) { + if (pFunc->func.attr.fAttr2 & f2PASCAL) + HOut("__pascal "); + else if (pFunc->func.attr.fAttr2 & f2CDECL) + HOut("__cdecl "); + else if (pFunc->func.attr.fAttr2 & f2STDCALL) + HOut("__stdcall "); +#ifdef DEBUG + else Assert(FALSE); +#endif //DEBUG + } + + HOutPropPrefix(pFunc); + XOutF(pFunc->func.szElemName); + + Assert(pFunc->func.elemType->tdesc.vt != VT_CARRAY); + + XOut("("); + +#ifdef PROFILE + cArgsTotal += pFunc->cArgs; + cFuncsTotal++; +#endif //PROFILE + if (pFunc->cArgs == 0) + { + HOut("void"); + } + else + { + // output list of variables, separating them by + // commas, with nothing after last item + HOutElems(pFunc->argList, "", ", ", "", FALSE); +#ifdef PROFILE + cVarsTotal-= pFunc->cArgs; // would be counted twice +#endif //PROFILE + } + XOut(");\n"); + } + + // advance to next entry if not all done + if (pFunc == (LPFUNC)ListLast(pFuncList)) + break; // exit if all done + pFunc = (LPFUNC)pFunc->func.pNext; + } + + if (fSpecifiedInterCC) { + SetCallType(CALL_DEFAULT); // reset to default STDMETHODCALLTYPE + } +} + + +VOID NEAR SetCallType +( + CALLINGCONV cc +) +{ + Assert (fSpecifiedInterCC); // caller should have checked + if (cc != ccInterCurrent) + { // if current different than last + HOut(szUndefCallType); // undefine current STDMETHODCALLTYPE + if (cc == CALL_DEFAULT) { + HOut(szResetCallType); // reset to default + } else { + HOut(szDefCallTypePrefix); // re-define to new value + HOut(rgszCallType[cc]); + HOut("\n"); + } + + ccInterCurrent = cc; // update current value + } +} + + +VOID NEAR HOutPropPrefix +( + LPFUNC pFunc +) +{ + // add a prefix to the function name if this is a property function + if (pFunc->func.attr.fAttr & fPROPGET) + HOut("get_"); + else if (pFunc->func.attr.fAttr & fPROPPUT) + HOut("put_"); + else if (pFunc->func.attr.fAttr & fPROPPUTREF) + HOut("putref_"); +} + + +VOID NEAR HOutShortNum +( + SHORT num, + BOOL fHex +) +{ + CHAR szBuffer[30]; // space to list a number + + sprintf(szBuffer, + fHex ? "0x%hX" : "%hd", + num); + HOut(szBuffer); +} + + +VOID NEAR HOutLongNum +( + LONG num, + BOOL fHex +) +{ + CHAR szBuffer[30]; // space to list a number + + // Stupid C will choke if this number is printed in decimal + if (num == 0x80000000) + fHex = TRUE; + + sprintf(szBuffer, + fHex ? "0x%lX" : "%ld", + num); + HOut(szBuffer); +} + +VOID NEAR HOutElems +( + LPELEM pElemList, + CHAR * szPrefix, + CHAR * szSep, + CHAR * szSepLast, + BOOL fEnum +) +{ + + LPELEM pElem; + WORD cDims; + ARRAYDESC FAR* lpAD; + BOOL fHex; + LPOLESTR lpch; + CHAR * pch; + CHAR buf[2]; + UINT cch; + + pElem = (LPELEM)ListFirst(pElemList); // point to first entry + +#pragma warning(disable:4127) + while (TRUE) +#pragma warning(default:4127) + { + HOut(szPrefix); + if (!fEnum) + { + // output elem type, with the right number of "*'s" + HOutType(pElem->elemType); + HOut(" "); + } + + XOutF(pElem->szElemName); +#ifdef PROFILE + cVarsTotal++; +#endif //PROFILE + + if (!fEnum && pElem->elemType->tdesc.vt == VT_CARRAY) + { // base type already outputted before name above + lpAD = pElem->elemType->tdesc.lpadesc; + for (cDims = 0; cDims < lpAD->cDims; cDims++) + { + HOut("["); +#if 0 // arrays of the form "a[]" aren't supported + if (lpAD->rgbounds[cDims].cElements) +#endif //0 + HOutLongNum((long)lpAD->rgbounds[cDims].cElements, FALSE); + HOut("]"); + } + + } + + if (pElem->attr.fAttr2 & f2GotConstVal) + { + HOut(" = "); + + fHex = FALSE; + if (!fEnum) { + // display all the unsigned constants in Hex form + switch (pElem->elemType->tdesc.vt) { + case VT_UI1: + case VT_UI2: + case VT_UI4: + case VT_UINT: + case VT_ERROR: + fHex = TRUE; + break; + default: + break; + } + } + + // output the constant element's value + switch (pElem->lpElemVal->vt) + { + case VT_I2: + case VT_BOOL: + HOutShortNum(pElem->lpElemVal->iVal, fHex); + break; + case VT_I4: + case VT_ERROR: + HOutLongNum(pElem->lpElemVal->lVal, fHex); + break; + case VT_BSTR: + HOut("\""); + // output 1 char at a time, in order to handle + // escape sequences in strings + lpch = pElem->lpElemVal->bstrVal; + cch = SysStringLen(lpch); + while (cch) { + switch(*lpch) { + case 0x0: + pch = "\\0"; + break; + case 0x7: + pch = "\\a"; + break; + case 0x8: + pch = "\\b"; + break; + case 0x9: + pch = "\\t"; + break; + case 0xA: + if (SysKind == SYS_MAC) + pch = "\\r"; + else + pch = "\\n"; + break; + case 0xB: + pch = "\\v"; + break; + case 0xC: + pch = "\\f"; + break; + case 0xD: + if (SysKind == SYS_MAC) + pch = "\\n"; + else + pch = "\\r"; + break; + default: +#ifdef WIN32 + SideAssert (WideCharToMultiByte(CP_ACP, + 0, + lpch, + 1, + buf, + 1, + NULL, + NULL) != 0); +#else //WIN32 + buf[0] = *lpch; +#endif //WIN32 + buf[1] = '\0'; + pch = buf; + break; + } + HOut(pch); // output the char + lpch++; + cch--; + } + HOut("\""); + break; + // CONSIDER: support more constant types. + default: + Assert(FALSE); + } + + } + + // advance to next entry if not all done + if (pElem == (LPELEM)ListLast(pElemList)) + { + XOut(szSepLast); + break; // exit if all done + } + XOut(szSep); + pElem = pElem->pNext; + } + +} + + +VOID NEAR HOutType +( + LPTYPE pType +) +{ + SHORT i; + CHAR * szPrefix; + + switch (pType->tdesc.vt) + { + case VT_PTR: + // first output the base type + HOutType(pType->ref.ptypeBase); + + // now output the proper number of "*"'s + Assert (pType->ref.cIndirect != 0); + for (i = pType->ref.cIndirect; i > 0; i--) + { + // always output "FAR" for constency (same as dispatch.h) + HOut(" FAR*"); + } + break; + + case VT_CARRAY: + // just output the base type -- we'll handle this stuff + // after we output the name + HOutType(pType->ref.ptypeBase); + break; + + case VT_SAFEARRAY: + HOut("SAFEARRAY FAR*"); + break; + + case VT_BOOL: // special case -- "boolean" no good + HOut("VARIANT_BOOL"); + break; + + case VT_CY: // special case -- "CURRENCY" no good + HOut("CY"); + break; + + default: + // output "unsigned" if necessary + if (pType->tentrykind == tINTRINSIC && pType->intr.fUnsigned) + HOut("unsigned "); + + switch (pType->tentrykind & ~tFORWARD) + { + case tUNION: + szPrefix = "union "; + goto outputPrefix; + + case tSTRUCT: + szPrefix = "struct "; +outputPrefix: + if (pType->structenum.szTag) + { + HOut(szPrefix); + HOutF(pType->structenum.szTag); + break; + } + // otherwise, fall into default processing + + default: + HOutF(pType->szName); + + } + break; + } + +} + +VOID NEAR HOutGuid +( + LPATTR pAttr, + CHAR * szGuidPrefix, + LPSTR lpszName +) +{ + CHAR szBuffer[100]; // space to list a number UNDONE: Tune + GUID FAR * lpGuid; + + if ((pAttr->fAttr & fUUID) == 0) + return; // no guid to output + + lpGuid = pAttr->lpUuid; + HOut(szHeadGuidPrefix); + HOut(szGuidPrefix); // prefix the user's name + HOutF(lpszName); // add the user's name + sprintf(szBuffer, ",0x%.8lX,0x%.4X,0x%.4X,0x%.2X,0x%.2X,0x%.2X,0x%.2X,0x%.2X,0x%.2X,0x%.2X,0x%.2X);\n", + lpGuid->Data1, + lpGuid->Data2, + lpGuid->Data3, + lpGuid->Data4[0], + lpGuid->Data4[1], + lpGuid->Data4[2], + lpGuid->Data4[3], + lpGuid->Data4[4], + lpGuid->Data4[5], + lpGuid->Data4[6], + lpGuid->Data4[7] + ); + HOut(szBuffer); +} + +VOID NEAR HOutF +( + LPSTR lpszData +) +{ + CHAR szBuffer[256]; + + _fstrcpy(szBuffer, lpszData); // copy data near + + HOut(szBuffer); // output it +} + + +VOID NEAR HOut +( + CHAR * szData +) +{ + if (fputs(szData, hHFile) < 0) // write the data + ParseError(ERR_WRITING_HFILE); +} + +#ifdef PROFILE +VOID NEAR XOutF +( + LPSTR lpszData +) +{ + CHAR szBuffer[256]; + + _fstrcpy(szBuffer, lpszData); // copy data near + + XOut(szBuffer); // output it +} + + +VOID NEAR XOut +( + CHAR * szData +) +{ + printf(szData); // output to console +} + +#endif //PROFILE |