unit uRODLConvertersUtils; {----------------------------------------------------------------------------} { RemObjects SDK Library - CodeGen2 } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$IFNDEF MSWINDOWS} {$I ../RemObjects.inc} {$ELSE} {$I ..\RemObjects.inc} {$ENDIF} interface uses {$IFDEF FPC}LResources,{$ENDIF} Classes, uRODLImplConverter, uRODLToXML, uRODL; const DEFAULT_DELPHI_INTF_TEMPLATE_FILENAME = 'template.intf.pas'; DEFAULT_DELPHI_INVK_TEMPLATE_FILENAME = 'template.invk.pas'; DEFAULT_DELPHI_IMPL_TEMPLATE_FILENAME = 'template.impl.pas'; DEFAULT_DELPHI_ASYNC_TEMPLATE_FILENAME = 'template.async.pas'; DEFAULT_DELPHI_INTF_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_intf.pas'; DEFAULT_DELPHI_INVK_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_invk.pas'; DEFAULT_DELPHI_ASYNC_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_async.pas'; DEFAULT_CPP_INTF_TEMPLATE_FILENAME = 'template.intf.cpp'; DEFAULT_CPP_INVK_TEMPLATE_FILENAME = 'template.invk.cpp'; DEFAULT_CPP_IMPL_TEMPLATE_FILENAME = 'template.impl.cpp'; DEFAULT_CPP_ASYNC_TEMPLATE_FILENAME = 'template.async.cpp'; DEFAULT_CPP_INTF_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_intf.h'; DEFAULT_CPP_INVK_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_invk.h'; DEFAULT_CPP_ASYNC_WRAPPER_TEMPLATE_FILENAME = 'template.wrapper_async.h'; {$IFNDEF FPC} {$R Templates\Templates.res} {$ENDIF} type TROCodeGenLanguage = (cglDelphiWin32, cglCppBuilder, cglCpp, cglObjectiveC); TROCodeGenType = (cgtIntf, cgtInvk, cgtImpl, cgtAsync, cgtRes); // Delphi procedure GenerateDelphiIntf(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiInvk(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiImpl(const LibraryFileName: string; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateDelphiAsync(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiIntf(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiInvk(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiImpl(const aLibrary: TRODLLibrary; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateDelphiAsync(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiIntf(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiInvk(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateDelphiImpl(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputDFMStream: TStream; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateDelphiAsync(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; // Cpp procedure GenerateCppIntf(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppInvk(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppImpl(const LibraryFileName: string; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateCppAsync(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppIntf(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppInvk(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppImpl(const aLibrary: TRODLLibrary; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateCppAsync(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppIntf(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppInvk(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateCppImpl(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const OutputDFMStream: TStream; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); overload; procedure GenerateCppAsync(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateUnitToStream(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aStream, aStream2: TStream; aAncestorName: string = ''; aUnitname: string = ''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); procedure GenerateUnitToFile(aLibraryFileName: string; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aAncestorName: string = ''; aFilename: string = ''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); overload; procedure GenerateUnitToFile(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aAncestorName: string = ''; aFilename: string = ''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); overload; // Misc. function GetTargetFileName(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage): string; implementation uses SysUtils, uRODLTemplateBasedConverterUtils, uRODLDelphiConverters, uRODLCppConverters; // Delphi procedure GenerateDelphiIntf(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateDelphiIntf(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateDelphiInvk(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateDelphiInvk(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateDelphiImpl(const LibraryFileName: string; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateDelphiImpl(lib, ServiceName, TemplateFileName, AncestorName, OutputFileName, aRequiredUnits); finally lib.Free; end; end; procedure GenerateDelphiAsync(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateDelphiAsync(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateDelphiIntf(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INTF_SUFFIX + '.pas' else outputName := OutputFileName; outputStream := TMemoryStream.Create; try GenerateDelphiIntf(aLibrary, outputStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, Entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); finally outputStream.Free; end; end; procedure GenerateDelphiInvk(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INVK_SUFFIX + '.pas' else outputName := OutputFileName; outputStream := TMemoryStream.Create; try GenerateDelphiInvk(aLibrary, outputStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, Entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); finally outputStream.Free; end; end; procedure GenerateDelphiImpl(const aLibrary: TRODLLibrary; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var outputName: string; outputStream: TMemoryStream; outputDFMStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := ServiceName + DEFAULT_IMPL_SUFFIX + '.pas' else outputName := OutputFileName; outputStream := TMemoryStream.Create; outputDFMStream := TMemoryStream.Create; try GenerateDelphiImpl(aLibrary, outputStream, outputDFMStream, ServiceName, TemplateFileName, AncestorName, OutputFileName, aRequiredUnits); outputStream.SaveToFile(outputName); if outputDFMStream.Size > 0 then outputDFMStream.SaveToFile(ChangeFileExt(outputName, '.dfm')); finally outputDFMStream.Free; outputStream.Free; end; end; procedure GenerateDelphiAsync(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_ASYNC_SUFFIX + '.pas' else outputName := OutputFileName; outputStream := TMemoryStream.Create; try GenerateDelphiAsync(aLibrary, outputStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); finally outputStream.Free; end; end; procedure GenerateDelphiIntf(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var gen: TRODLDelphiIntfConverter; templateName: string; outputName: string; unitName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_DELPHI_INTF_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_DELPHI_INTF_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INTF_SUFFIX + '.pas' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLDelphiIntfConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(OutputStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateDelphiIntf(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_INTF_SUFFIX + '.pas', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; procedure GenerateDelphiInvk(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var gen: TRODLDelphiInvkConverter; templateName: string; outputName: string; unitName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_DELPHI_INVK_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_DELPHI_INVK_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INVK_SUFFIX + '.pas' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLDelphiInvkConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(OutputStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateDelphiInvk(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_INVK_SUFFIX + '.pas', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; procedure GenerateDelphiImpl(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputDFMStream: TStream; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var gen: TRODLDelphiImplConverter; templateName: string; outputName: string; unitName: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_DELPHI_IMPL_TEMPLATE_FILENAME else templateName := TemplateFileName; if Length(OutputFileName) = 0 then outputName := ServiceName + DEFAULT_IMPL_SUFFIX + '.pas' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLDelphiImplConverter.Create(aLibrary, templateName, unitName, AncestorName, ServiceName, aRequiredUnits); try gen.SaveResultToStream(OutputStream); // If datamodule then generate DFM if gen.WriteDataModule then begin gen.TemplateFileName := ChangeFileExt(templateName, '.dfm'); gen.FileExtension := '.dfm'; gen.Convert(aLibrary, ServiceName); gen.SaveResultToStream(OutputDFMStream); end; finally gen.Free; end; end; procedure GenerateDelphiAsync(const aLibrary: TRODLLibrary; const OutputStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var gen: TRODLDelphiAsyncConverter; templateName: string; outputName: string; unitName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_DELPHI_ASYNC_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_DELPHI_ASYNC_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_ASYNC_SUFFIX + '.pas' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLDelphiAsyncConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(outputStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateDelphiAsync(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_ASYNC_SUFFIX + '.pas', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; // Cpp procedure GenerateCppIntf(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateCppIntf(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateCppInvk(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateCppInvk(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateCppImpl(const LibraryFileName: string; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateCppImpl(lib, ServiceName, TemplateFileName, AncestorName, OutputFileName, aRequiredUnits); finally lib.Free; end; end; procedure GenerateCppAsync(const LibraryFileName: string; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var lib: TRODLLibrary; begin lib := ReadRODLFromFile(TXMLToRODL, LibraryFileName); try GenerateCppAsync(lib, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); finally lib.Free; end; end; procedure GenerateCppIntf(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; outputHStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INTF_SUFFIX + '.cpp' else outputName := OutputFileName; outputStream := TMemoryStream.Create; outputHStream := TMemoryStream.Create; try GenerateCppIntf(aLibrary, outputStream, outputHStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); outputHStream.SaveToFile(ChangeFileExt(outputName, '.h')); finally outputHStream.Free; outputStream.Free; end; end; procedure GenerateCppInvk(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; outputHStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INVK_SUFFIX + '.cpp' else outputName := OutputFileName; outputStream := TMemoryStream.Create; outputHStream := TMemoryStream.Create; try GenerateCppInvk(aLibrary, outputStream, outputHStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); outputHStream.SaveToFile(ChangeFileExt(outputName, '.h')); finally outputHStream.Free; outputStream.Free; end; end; procedure GenerateCppImpl(const aLibrary: TRODLLibrary; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var outputName: string; outputStream: TMemoryStream; outputHStream: TMemoryStream; outputDFMStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := ServiceName + DEFAULT_IMPL_SUFFIX + '.cpp' else outputName := OutputFileName; outputStream := TMemoryStream.Create; outputHStream := TMemoryStream.Create; outputDFMStream := TMemoryStream.Create; try GenerateCppImpl(aLibrary, outputStream, outputHStream, outputDFMStream, ServiceName, TemplateFileName, AncestorName, OutputFileName, aRequiredUnits); outputStream.SaveToFile(outputName); outputHStream.SaveToFile(ChangeFileExt(outputName, '.h')); if outputDFMStream.Size > 0 then outputDFMStream.SaveToFile(ChangeFileExt(outputName, '.dfm')); finally outputDFMStream.Free; outputHStream.Free; outputStream.Free; end; end; procedure GenerateCppAsync(const aLibrary: TRODLLibrary; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var outputName: string; outputStream: TMemoryStream; outputHStream: TMemoryStream; begin if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_ASYNC_SUFFIX + '.cpp' else outputName := OutputFileName; outputStream := TMemoryStream.Create; outputHStream := TMemoryStream.Create; try GenerateCppAsync(aLibrary, outputStream, outputHStream, TemplateFileName, OutputFileName, ASplit, AWrapperTemplateName, entities, GenerateUsedRODLS); outputStream.SaveToFile(outputName); outputHStream.SaveToFile(ChangeFileExt(outputName, '.h')); finally outputHStream.Free; outputStream.Free; end; end; procedure GenerateCppIntf(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var templateName: string; gen: TRODLCppIntfConverter; outputName: string; unitName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_CPP_INTF_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_CPP_INTF_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INTF_SUFFIX + '.cpp' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLCppIntfConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(OutputStream); gen.TemplateFileName := ChangeFileExt(templateName, '.h'); gen.FileExtension := '.h'; gen.Convert(aLibrary); gen.SaveResultToStream(OutputHStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateCppIntf(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_INTF_SUFFIX + '.cpp', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; procedure GenerateCppInvk(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var gen: TRODLCppInvkConverter; templateName: string; unitName: string; outputName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_CPP_INVK_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_CPP_INVK_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_INVK_SUFFIX + '.cpp' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLCppInvkConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(OutputStream); gen.TemplateFileName := ChangeFileExt(templateName, '.h'); gen.FileExtension := '.h'; gen.Convert(aLibrary); gen.SaveResultToStream(OutputHStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateCppInvk(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_INVK_SUFFIX + '.cpp', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; procedure GenerateCppImpl(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const OutputDFMStream: TStream; const ServiceName: string; const TemplateFileName: string = ''; const AncestorName: string = DEFAULT_IMPL_SERVICE_ANCESTOR; const OutputFileName: string = ''; const aRequiredUnits: string = ''); var gen: TRODLCppImplConverter; templateName: string; outputName: string; unitName: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_CPP_IMPL_TEMPLATE_FILENAME else templateName := TemplateFileName; if Length(OutputFileName) = 0 then outputName := ServiceName + DEFAULT_IMPL_SUFFIX + '.cpp' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLCppImplConverter.Create(aLibrary, templateName, unitName, AncestorName, ServiceName, aRequiredUnits); try gen.SaveResultToStream(outputStream); gen.TemplateFileName := ChangeFileExt(templateName, '.h'); gen.FileExtension := '.h'; gen.Convert(aLibrary, ServiceName); gen.SaveResultToStream(outputHStream); // If datamodule then generate DFM if gen.WriteDataModule then begin gen.TemplateFileName := ChangeFileExt(templateName, '.dfm'); gen.FileExtension := '.dfm'; gen.Convert(aLibrary, ServiceName); gen.SaveResultToStream(outputDFMStream); end; finally gen.Free; end; end; procedure GenerateCppAsync(const aLibrary: TRODLLibrary; const OutputStream: TStream; const OutputHStream: TStream; const TemplateFileName: string = ''; const OutputFileName: string = ''; const ASplit: Boolean = False; const AWrapperTemplateName: string = ''; const entities: string = ''; GenerateUsedRODLS: Boolean = False); var templateName: string; gen: TRODLCppAsyncConverter; outputName: string; unitName: string; wrapperTemplateName: string; i: Integer; TmpSplit: Boolean; RODLToUse: string; begin if (Length(TemplateFileName) = 0) or not FileExists(TemplateFileName) then templateName := DEFAULT_CPP_ASYNC_TEMPLATE_FILENAME else templateName := TemplateFileName; if (Length(AWrapperTemplateName) = 0) or not FileExists(AWrapperTemplateName) then wrapperTemplateName := DEFAULT_CPP_ASYNC_WRAPPER_TEMPLATE_FILENAME else wrapperTemplateName := AWrapperTemplateName; if Length(OutputFileName) = 0 then outputName := aLibrary.Name + DEFAULT_ASYNC_SUFFIX + '.cpp' else outputName := OutputFileName; unitName := ChangeFileExt(ExtractFileName(outputName), ''); ClearAllCaches; gen := TRODLCppAsyncConverter.Create(aLibrary, templateName, unitName, ASplit, ExtractFilePath(outputName), wrapperTemplateName, entities); try gen.SaveResultToStream(OutputStream); gen.TemplateFileName := ChangeFileExt(templateName, '.h'); gen.FileExtension := '.h'; gen.Convert(aLibrary); gen.SaveResultToStream(OutputHStream); finally gen.Free; end; if GenerateUsedRODLs then begin for i := 0 to aLibrary.UseCount-1 do begin if (aLibrary.Use[i].GenerateCode) then begin case aLibrary.Use[i].SplitMode of usmNever: TmpSplit := False; usmAlways: TmpSplit := True; else TmpSplit := ASplit; end; RODLToUse := ExpandVariables(aLibrary.Use[i].RodlFile); if not FileExists(RODLTouse) then RODLToUse := aLibrary.Use[i].AbsoluteRodlFile; GenerateCppAsync(RODLToUse, TemplateFileName, ChangeFileExt(RODLToUse, '') + DEFAULT_ASYNC_SUFFIX + '.cpp', TmpSplit, AWrapperTemplateName, entities, GenerateUsedRODLS); end; end; end; end; procedure GenerateUnitToStream(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aStream, aStream2: TStream; aAncestorName: string = ''; aUnitname: string = ''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); begin if aUnitname = '' then aUnitname := GetTargetFileName(aLibrary, aService, aType, aLanguage); if aAncestorName = '' then aAncestorName := 'TRORemotable'; case aLanguage of cglDelphiWin32: begin case aType of cgtIntf : GenerateDelphiIntf(aLibrary, aStream, '', aUnitname, False, '', '', GenerateUsedRODLS); cgtInvk : GenerateDelphiInvk(aLibrary, aStream, '', aUnitname, False, '', '', GenerateUsedRODLS); cgtImpl : GenerateDelphiImpl(aLibrary, aStream,aStream2, aService.Name, '',aAncestorName, aUnitname, aRequiredUnits); //raise Exception.Create('not supported.'); cgtAsync: GenerateDelphiAsync(aLibrary, aStream, '', aUnitname, False, '', '', GenerateUsedRODLS); end; end; cglCppBuilder: begin case aType of cgtIntf : GenerateCppIntf(aLibrary, aStream, aStream2, '', aUnitname, False, '', '', GenerateUsedRODLS); cgtInvk : GenerateCppInvk(aLibrary, aStream, aStream2, '', aUnitname, False, '', '', GenerateUsedRODLS); cgtImpl : raise Exception.Create('not supported.'); cgtAsync: GenerateCppAsync(aLibrary, aStream, aStream2, '', aUnitname, False, '', '', GenerateUsedRODLS); end; end; end; end; procedure GenerateUnitToFile(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aAncestorName: string = ''; aFilename: string=''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); begin if aFilename = '' then aFilename := GetTargetFileName(aLibrary, aService, aType, aLanguage); if aAncestorName = '' then aAncestorName := 'TRORemotable'; case aLanguage of cglDelphiWin32: begin case aType of cgtIntf : GenerateDelphiIntf(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); cgtInvk : GenerateDelphiInvk(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); cgtImpl : GenerateDelphiImpl(aLibrary, aService.Name, '', aAncestorName, aFilename, aRequiredUnits); cgtAsync: GenerateDelphiAsync(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); end; end; cglCppBuilder: begin case aType of cgtIntf : GenerateCppIntf(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); cgtInvk : GenerateCppInvk(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); cgtImpl : GenerateCppImpl(aLibrary, aService.Name, '', aAncestorName, aFilename, aRequiredUnits); cgtAsync: GenerateCppAsync(aLibrary, '', aFilename, False, '', '', GenerateUsedRODLS); end; end; end; end; procedure GenerateUnitToFile(aLibraryFileName: string; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage; aAncestorName: string = ''; aFilename: string = ''; aRequiredUnits: string = ''; GenerateUsedRODLS: Boolean = False); var lLibrary: TRODLLibrary; begin lLibrary := LoadLibraryFromXml(aLibraryFileName); try GenerateUnitToFile(lLibrary, aService, aType, aLanguage, aAncestorName, aFileName, aRequiredUnits); finally lLibrary.Free(); end; end; function GetTargetFileName(aLibrary: TRODLLibrary; aService:TRODLService; aType: TROCodeGenType; aLanguage: TROCodeGenLanguage): string; begin case aType of cgtIntf : result := aLibrary.Name + DEFAULT_INTF_SUFFIX; cgtInvk : result := aLibrary.Name + DEFAULT_INVK_SUFFIX; cgtImpl : result := aService.Name + DEFAULT_IMPL_SUFFIX; cgtAsync: result := aLibrary.Name + DEFAULT_ASYNC_SUFFIX; end; case aLanguage of cglDelphiWin32: result := result+'.pas'; cglCpp, cglCppBuilder: result := result+'.cpp'; cglObjectiveC: result := result+'.m'; end; end; {$IFDEF FPC} initialization {$IFDEF MSWINDOWS} {$I Templates\Templates.lrs} {$ELSE} {$I Templates/Templates.lrs} {$ENDIF} {$ENDIF FPC} end.