You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
7.1 KiB
221 lines
7.1 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
idltoxml.cpp
|
|
|
|
Abstract:
|
|
|
|
From a .ppm that included .idl, generate .xml.
|
|
Based on base\wow64\tools\gennt32t.cpp.
|
|
The .tpl language doesn't seem to provide for enumerating types, and the .ppm
|
|
files are pretty easy to read directly and apply arbitrary/flexible C/C++ logic to.
|
|
Writing .tpl is actually a significant extra learning curve beyond reading .ppm files.
|
|
|
|
Author:
|
|
|
|
Jay Krell (JayKrell) August 2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "windows.h"
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#define NUMBER_OF(x) (sizeof(x)/sizeof((x)[0]))
|
|
|
|
extern "C" {
|
|
|
|
#include "gen.h"
|
|
|
|
// string to put in front of all error messages so that BUILD can find them.
|
|
const char *ErrMsgPrefix = "NMAKE : U8603: 'IDLTOXML' ";
|
|
|
|
void
|
|
HandlePreprocessorDirective(
|
|
char *
|
|
)
|
|
{
|
|
ExitErrMsg(FALSE, "Preprocessor directives not allowed by gennt32t.\n");
|
|
}
|
|
|
|
}
|
|
|
|
const char g_Indent[] = " ";
|
|
|
|
PRBTREE Functions = NULL;
|
|
PRBTREE Structures = NULL;
|
|
PRBTREE Typedefs = NULL;
|
|
PKNOWNTYPES NIL = NULL;
|
|
|
|
void ExtractCVMHeader(PCVMHEAPHEADER Header)
|
|
{
|
|
Functions = &Header->FuncsList;
|
|
Typedefs = &Header->TypeDefsList;
|
|
Structures = &Header->StructsList;
|
|
NIL = &Header->NIL;
|
|
}
|
|
|
|
void GuidToString(GUID g, char * s)
|
|
{
|
|
sprintf(
|
|
s, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
|
g.Data1, g.Data2, g.Data3, g.Data4[0], g.Data4[1], g.Data4[2],
|
|
g.Data4[3], g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]);
|
|
|
|
}
|
|
|
|
void IdlToXml(int /*argc*/, char** argv)
|
|
{
|
|
const char * Indent = &g_Indent[NUMBER_OF(g_Indent) - 1];
|
|
ExtractCVMHeader(MapPpmFile(argv[1], TRUE));
|
|
PKNOWNTYPES Type = NULL;
|
|
|
|
for(Type = Structures->pLastNodeInserted; Type != NULL; Type = Type->Next)
|
|
{
|
|
char GuidAsString[64];
|
|
|
|
//printf("%s\n", Type->TypeName);
|
|
|
|
if ((Type->Flags & BTI_ISCOM) == 0
|
|
|| (Type->Flags & BTI_HASGUID) == 0)
|
|
continue;
|
|
|
|
//
|
|
// skip anything out of publics (hacky..)
|
|
//
|
|
if (strstr(Type->FileName, "\\public\\") != NULL
|
|
|| strstr(Type->FileName, "\\PUBLIC\\") != NULL
|
|
|| strstr(Type->FileName, "\\Public\\") != NULL
|
|
)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//printf("%s\n", Type->FileName);
|
|
|
|
GuidToString(Type->gGuid, GuidAsString);
|
|
|
|
printf("%sinterface\n%s__declspec(uuid(\"%s\"))\n%s%s : %s\n",
|
|
Indent, Indent,
|
|
GuidAsString,
|
|
Indent,
|
|
Type->TypeName, Type->BaseType
|
|
);
|
|
printf("%s{\n", Indent);
|
|
Indent -= 4;
|
|
|
|
//
|
|
// IMethods is a multisz thingy, and then we find those strings in the list of functions.
|
|
//
|
|
// hackety hack..maybe this is what the sortpp author intended,
|
|
// the information is clearly determined during parse, but then not really put in the .ppm
|
|
// sortpp does generate the declarations of the proxies if they are missing, so maybe
|
|
// this is the intended usage..
|
|
for ( char * imeth = Type->IMethods ; *imeth ; imeth += 1 + strlen(imeth) )
|
|
{
|
|
char ProxyFunctionName[MAX_PATH];
|
|
sprintf(ProxyFunctionName, "%s_%s_Proxy", Type->TypeName, imeth);
|
|
PKNOWNTYPES ProxyFunction = GetNameFromTypesList(Functions, ProxyFunctionName);
|
|
if (ProxyFunction == NULL)
|
|
{
|
|
printf("error MemberFunction == NULL (%s, %s)\n", Type->TypeName, imeth);
|
|
continue;
|
|
}
|
|
PCSTR FuncMod = ProxyFunction->FuncMod;
|
|
if (FuncMod == NULL)
|
|
FuncMod = "";
|
|
if (strcmp(FuncMod, "__stdcall") == 0)
|
|
FuncMod = "";
|
|
printf("%s%s%s%s%s%s(\n%s",
|
|
Indent, ProxyFunction->FuncRet,
|
|
(FuncMod[0] != 0) ? " " : "",
|
|
(FuncMod[0] != 0) ? FuncMod : " ",
|
|
(FuncMod[0] != 0) ? " " : "",
|
|
imeth,
|
|
Indent - 4
|
|
);
|
|
Indent -= 4;
|
|
PFUNCINFO Parameter = ProxyFunction->pfuncinfo;
|
|
if (Parameter != NULL)
|
|
{
|
|
// skip the this pointer
|
|
bool comma = false;
|
|
for (Parameter = Parameter->pfuncinfoNext; Parameter != NULL ; Parameter = Parameter->pfuncinfoNext )
|
|
{
|
|
if (comma)
|
|
{
|
|
printf(",\n%s", Indent);
|
|
}
|
|
comma = true;
|
|
switch (Parameter->tkDirection)
|
|
{
|
|
default:
|
|
case TK_NONE:
|
|
break;
|
|
case TK_IN:
|
|
printf("[in] ");
|
|
break;
|
|
case TK_OUT:
|
|
printf("[out] ");
|
|
break;
|
|
case TK_INOUT:
|
|
printf("[in][out] ");
|
|
break;
|
|
}
|
|
//
|
|
// This seems to be a bug in sortpp, it only has the notion of there being
|
|
// up to occurences of "const" or "volatile", but any number of stars?
|
|
// C/C++ and perhaps are .idl more general than that.
|
|
//
|
|
switch (Parameter->tkPreMod)
|
|
{
|
|
default:
|
|
case TK_NONE:
|
|
break;
|
|
case TK_CONST:
|
|
printf("const ");
|
|
break;
|
|
case TK_VOLATILE:
|
|
printf("volatile ");
|
|
break;
|
|
}
|
|
printf(" %s ", Parameter->sType);
|
|
for (int IndLevel = Parameter->IndLevel ; IndLevel != 0 ; --IndLevel)
|
|
{
|
|
printf(" * ");
|
|
}
|
|
switch (Parameter->tkPostMod)
|
|
{
|
|
default:
|
|
case TK_NONE:
|
|
break;
|
|
case TK_CONST:
|
|
printf("const ");
|
|
break;
|
|
case TK_VOLATILE:
|
|
printf("volatile ");
|
|
break;
|
|
}
|
|
printf(Parameter->sName);
|
|
}
|
|
}
|
|
printf("\n%s);\n", Indent);
|
|
Indent += 4;
|
|
}
|
|
Indent += 4;
|
|
printf("%s};\n\n", Indent);
|
|
}
|
|
}
|
|
|
|
int __cdecl main(int argc, char** argv)
|
|
{
|
|
IdlToXml(argc, argv);
|
|
return 0;
|
|
}
|