Back to index

lightning-sunbird  0.9+nobinonly
tlb2xpt.cpp
Go to the documentation of this file.
00001 // tlb2xpt.cpp : Defines the entry point for the console application.
00002 //
00003 
00004 #include "stdafx.h"
00005 
00006 #include "xpt_xdr.h"
00007 
00008 typedef void (*EnumTypeLibProc)(ITypeInfo *typeInfo, TYPEATTR *typeAttr);
00009 
00010 void EnumTypeLib(ITypeLib *typeLib, EnumTypeLibProc pfn);
00011 void EnumTypeLibProcVerbose(ITypeInfo *typeInfo, TYPEATTR *typeAttr);
00012 void EnumTypeLibProcXPIDL(ITypeInfo *typeInfo, TYPEATTR *typeAttr);
00013 void EnumTypeLibProcXPT(ITypeInfo *typeInfo, TYPEATTR *typeAttr);
00014 void EnumTypeLibProcStubs(ITypeInfo *typeInfo, TYPEATTR *typeAttr);
00015 
00016 void DumpXPCOMInterfaceXPT(FILE *f, ITypeInfo *tiInterface);
00017 void DumpXPCOMInterfaceIDL(FILE *f, ITypeInfo *typeInfo);
00018 void DumpXPCOMInterfaceStubH(FILE *f, ITypeInfo *tiInterface);
00019 void DumpXPCOMInterfaceStubC(FILE *f, ITypeInfo *tiInterface);
00020 
00021 FILE *fidl   = NULL;
00022 FILE *fxpt   = NULL;
00023 FILE *fstubc = NULL;
00024 FILE *fstubh = NULL;
00025 
00026 int main(int argc, char* argv[])
00027 {
00028     BOOL verbose = FALSE;
00029     BOOL genIDL = FALSE;
00030     BOOL genXPT = FALSE;
00031     BOOL genStubs = FALSE;
00032     
00033     char *inputTLB = NULL;
00034     char *output = NULL;
00035 
00036     for (int arg = 1; arg < argc; arg++)
00037     {
00038         if (stricmp(argv[arg], "-verbose") == 0)
00039         {
00040             verbose = TRUE;
00041         }
00042         else if (stricmp(argv[arg], "-idl") == 0)
00043         {
00044             genIDL = TRUE;
00045         }
00046         else if (stricmp(argv[arg], "-xpt") == 0)
00047         {
00048             genXPT = TRUE;
00049         }
00050         else if (stricmp(argv[arg], "-stubs") == 0)
00051         {
00052             genStubs = TRUE;
00053         }
00054         else if (!inputTLB)
00055         {
00056           inputTLB = argv[arg];
00057         }
00058         else if (!output)
00059         {
00060             output = argv[arg];
00061         }
00062     }
00063     if (inputTLB == NULL || output == NULL)
00064     {
00065         fputs("Usage: tlb2xpt [-verbose] [-idl] [-stubs] [-xpt] typelibrary outputname\n"
00066               "  -verbose   Print out extra information\n"
00067               "  -idl       Generate an outputname.idl file\n"
00068               "  -xpt       Generate an outputname.xpt file\n"
00069               "  -stubs     Generate outputname.cpp and outputname.h stubs\n",
00070               stderr);
00071         return 1;
00072     }
00073 
00074     // Open FILE handles to the various things that need to be generated
00075     if (genIDL)
00076     {
00077         if (output)
00078         {
00079             std::string filename(output);
00080             filename += ".idl";
00081             fidl = fopen(filename.c_str(), "wt");
00082         }
00083         else
00084         {
00085             fidl = stdout;
00086         }
00087     }
00088     if (genXPT)
00089     {
00090         if (output)
00091         {
00092             std::string filename(output);
00093             filename += ".xpy";
00094             fxpt = fopen(filename.c_str(), "wb");
00095         }
00096     }
00097     if (genStubs)
00098     {
00099         std::string stubh(output);
00100         std::string stubc(output);
00101         stubh += ".h";
00102         stubc += ".cpp";
00103         fstubh = fopen(stubh.c_str(), "wt");
00104         fstubc = fopen(stubc.c_str(), "wt");
00105     }
00106 
00107     if (verbose)
00108         fprintf(stderr, "Opening TLB \"%s\"\n", inputTLB);
00109 
00110     ITypeLibPtr typeLib;
00111     USES_CONVERSION;
00112     HRESULT hr = LoadTypeLib(A2W(inputTLB), &typeLib);
00113     if (FAILED(hr))
00114     {
00115         fprintf(stderr, "Error: failed to open \"%s\"\n", inputTLB);
00116         return 1;
00117     }
00118 
00119     if (verbose)
00120         EnumTypeLib(typeLib, EnumTypeLibProcVerbose);
00121     
00122     if (genIDL)
00123     {
00124         fputs("#include \"axIUnknown.idl\"\n\n", fidl);
00125         EnumTypeLib(typeLib, EnumTypeLibProcXPIDL);
00126     }
00127 
00128     if (genXPT)
00129         EnumTypeLib(typeLib, EnumTypeLibProcXPT);
00130 
00131     if (genStubs)
00132     {
00133         EnumTypeLib(typeLib, EnumTypeLibProcStubs);
00134     }
00135 
00136     return 0;
00137 }
00138 
00139 
00140 
00141 void EnumTypeLibProcVerbose(ITypeInfo *typeInfo, TYPEATTR *typeAttr)
00142 {
00143     char *type;
00144     switch (typeAttr->typekind)
00145     {
00146     case TKIND_ENUM:
00147         type = "TKIND_ENUM";
00148         break;
00149     case TKIND_RECORD:
00150         type = "TKIND_RECORD";
00151         break;
00152     case TKIND_MODULE:
00153         type = "TKIND_MODULE";
00154         break;
00155     case TKIND_INTERFACE:
00156         type = "TKIND_INTERFACE";
00157         break;
00158     case TKIND_DISPATCH:
00159         type = "TKIND_DISPATCH";
00160         break;
00161     case TKIND_COCLASS:
00162         type = "TKIND_COCLASS";
00163         break;
00164     case TKIND_ALIAS:
00165         type = "TKIND_ALIAS";
00166         break;
00167     case TKIND_UNION:
00168         type = "TKIND_UNION";
00169         break;
00170     case TKIND_MAX:
00171         type = "TKIND_MAX";
00172         break;
00173     default:
00174         type = "default";
00175         break;
00176     }
00177     fprintf(stderr, "Reading %s type\n", type);
00178 }
00179 
00180 void EnumTypeLibProcXPT(ITypeInfo *typeInfo, TYPEATTR *typeAttr)
00181 {
00182     if (typeAttr->typekind == TKIND_INTERFACE)
00183     {
00184         DumpXPCOMInterfaceXPT(fxpt, typeInfo);
00185     }
00186 }
00187 
00188 void EnumTypeLibProcXPIDL(ITypeInfo *typeInfo, TYPEATTR *typeAttr)
00189 {
00190     if (typeAttr->typekind == TKIND_INTERFACE)
00191     {
00192         DumpXPCOMInterfaceIDL(fidl, typeInfo);
00193     }
00194 }
00195 
00196 
00197 void EnumTypeLibProcStubs(ITypeInfo *typeInfo, TYPEATTR *typeAttr)
00198 {
00199     if (typeAttr->typekind == TKIND_INTERFACE)
00200     {
00201         DumpXPCOMInterfaceStubH(fstubh, typeInfo);
00202         DumpXPCOMInterfaceStubC(fstubc, typeInfo);
00203     }
00204 }
00205 
00206 void EnumTypeLib(ITypeLib *typeLib, EnumTypeLibProc pfn)
00207 {
00208     UINT count = typeLib->GetTypeInfoCount();
00209     for (UINT i = 0; i < count; i++)
00210     {
00211         ITypeInfoPtr typeInfo;
00212         typeLib->GetTypeInfo(i, &typeInfo);
00213         TYPEATTR *typeAttr = NULL;
00214         typeInfo->GetTypeAttr(&typeAttr);
00215         pfn(typeInfo, typeAttr);
00216         typeInfo->ReleaseTypeAttr(typeAttr);
00217     }
00218 }
00219 
00220 
00221 // [scriptable, uuid(00000000-0000-0000-0000-000000000000)]
00222 // interface axIFoo : axIBar
00223 void DumpXPCOMInterfaceXPT(FILE *f, ITypeInfo *tiInterface)
00224 {
00225     XPTArena *arena = XPT_NewArena(1024 * 10, sizeof(double), "main xpt_link arena");
00226     // TODO. Maybe it would be better to just feed an IDL through the regular compiler
00227     //       than try and generate some XPT here.
00228     XPT_DestroyArena(arena);
00229 }
00230 
00231 void DumpXPCOMInterfaceStubH(FILE *f, ITypeInfo *tiInterface)
00232 {
00233     HRESULT hr;
00234 
00235     USES_CONVERSION;
00236     BSTR bstrName = NULL;
00237     hr = tiInterface->GetDocumentation(MEMBERID_NIL, &bstrName, NULL, NULL, NULL);
00238     char *name = strdup(W2A(bstrName));
00239     SysFreeString(bstrName);
00240 
00241     fputs("template<class T>\n", f);
00242     fprintf(f, "class nsAX%sImpl : public ax%s\n", name, name);
00243     fputs("{\n}", f);
00244 
00245     for (char *c = name; *c; c++)
00246     {
00247         *c = toupper(*c);
00248     }
00249     fprintf(f, "  NS_DECL_AX%s\n", name);
00250     fputs("};\n\n", f);
00251 
00252     free(name);
00253 }
00254 
00255 void DumpXPCOMInterfaceStubC(FILE *f, ITypeInfo *tiInterface)
00256 {
00257 
00258 }
00259 
00260 void DumpXPCOMInterfaceIDL(FILE *f, ITypeInfo *tiInterface)
00261 {
00262     HRESULT hr;
00263 
00264     // [scriptable, uuid(00000000-0000-0000-0000-000000000000)]
00265     // interface axIFoo : axIBar
00266     // {
00267     //    void method1();
00268     // };
00269 
00270     TYPEATTR *attr;
00271     tiInterface->GetTypeAttr(&attr);
00272 
00273     USES_CONVERSION;
00274 
00275     //
00276     // Attribute block
00277     //
00278     fputs("[scriptable, ", f);
00279 
00280     // uuid()
00281        WCHAR szGUID[64];
00282        StringFromGUID2(attr->guid, szGUID, sizeof(szGUID));
00283     szGUID[0] = L'(';
00284     szGUID[wcslen(szGUID) - 1] = L')';
00285     fprintf(f, "uuid%s", W2A(szGUID));
00286     
00287     fputs("]\n", f);
00288 
00289 
00290     //
00291     // Interface block
00292     //
00293 
00294     fprintf(f, "interface ");
00295 
00296     BSTR bstrName = NULL;
00297     hr = tiInterface->GetDocumentation(MEMBERID_NIL, &bstrName, NULL, NULL, NULL);
00298     fprintf(f, "ax%s", W2A(bstrName));
00299     SysFreeString(bstrName);
00300 
00301     // Check for the base interface
00302        for (UINT n = 0; n <  attr->cImplTypes; n++)
00303        {
00304               HREFTYPE href = NULL;
00305               if (FAILED(hr = tiInterface->GetRefTypeOfImplType(n, &href)))
00306            ;  // TODO
00307 
00308         ITypeInfoPtr tiParent;
00309               if (FAILED(hr = tiInterface->GetRefTypeInfo(href, &tiParent)))
00310            ; // TODO
00311 
00312               if (FAILED(hr = tiParent->GetDocumentation(MEMBERID_NIL, &bstrName, NULL, NULL, NULL)))
00313            ; // TODO
00314 
00315               fprintf(f, " : ax%s", W2A(bstrName));
00316 
00317               SysFreeString(bstrName);
00318         bstrName = NULL;
00319 
00320               tiParent.Release();
00321        }
00322 
00323 
00324     //
00325     // Methods and properties block
00326     //
00327 
00328     fprintf(f, "\n");
00329     fprintf(f, "{\n");
00330 
00331 
00332     for (n = 0; n < attr->cFuncs; n++)
00333     {
00334         FUNCDESC *func;
00335         tiInterface->GetFuncDesc(n, &func);
00336 
00337         fprintf(f, "  ");
00338         if (func->invkind & INVOKE_PROPERTYPUT ||
00339             func->invkind & INVOKE_PROPERTYGET)
00340               {
00341               }
00342 
00343         // Return type
00344         TypeDesc tf(tiInterface, &func->elemdescFunc.tdesc);
00345         if (tf.mType == TypeDesc::T_RESULT)
00346         {
00347             fprintf(f, "void ");
00348         }
00349         else
00350         {
00351             fprintf(f, "%s ", tf.ToXPIDLString().c_str());
00352         }
00353 
00354         // Method / property name
00355         BSTR bstrName = NULL;
00356        tiInterface->GetDocumentation(func->memid, &bstrName, NULL, NULL, NULL);
00357         fprintf(f, "%s (\n", W2A(bstrName));
00358         SysFreeString(bstrName);
00359 
00360         // Get the names of all the arguments
00361               UINT cNames;
00362            BSTR rgbstrNames[100];
00363               hr = tiInterface->GetNames(func->memid, rgbstrNames, 100, (UINT FAR*) &cNames);
00364 
00365         // Dump out all parameters
00366         for (int p = 0; p < func->cParams; p++)
00367         {
00368             fputs("    ", f);
00369 
00370             BOOL isIn = FALSE;
00371             BOOL isOut = FALSE;
00372 
00373             // Keywords
00374                      if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FRETVAL)
00375                      {
00376                             fputs("[retval] ", f);
00377                      }
00378                      if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FIN &&
00379                 func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FOUT)
00380             {
00381                 fputs("inout ", f);
00382             }
00383             else if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FIN)
00384             {
00385                 fputs("in ", f);
00386             }
00387             else if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FOUT)
00388             {
00389                 fputs("out ", f);
00390             }
00391 
00392             // Type
00393             // NOTE: If the arg is an out param, lop off the first pointer reference,
00394             //       because XPIDL implicitly expects out params to be pointers.
00395             TypeDesc tp(tiInterface, &func->lprgelemdescParam[p].tdesc);
00396             if (tp.mType == TypeDesc::T_POINTER &&
00397                 func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FOUT)
00398             {
00399                 fprintf(f, "%s ", tp.mData.mPtr->ToXPIDLString().c_str());
00400             }
00401             else
00402             {
00403                 // Type
00404                 fprintf(f, "%s ", tp.ToXPIDLString().c_str());
00405             }
00406 
00407             // Name
00408             fputs(W2A(rgbstrNames[p+1]), f);
00409 
00410             if (p < func->cParams - 1)
00411             {
00412                 fprintf(f, ",\n");
00413             }
00414             else
00415             {
00416                 fprintf(f, "\n");
00417             }
00418               SysFreeString(rgbstrNames[0]);
00419         }
00420         fputs("  );\n", f);
00421 
00422         tiInterface->ReleaseFuncDesc(func);
00423     }
00424 
00425 
00426     // Fin
00427     fputs("};\n\n", f);
00428 
00429     tiInterface->ReleaseTypeAttr(attr);
00430 }