private CppModule ParseCpp(CastXml castXml, CppModule group) { // Run the parser var parser = new CppParser(Logger, castXml) { OutputPath = IntermediateOutputPath }; parser.Initialize(Config); if (Logger.HasErrors) { Logger.Fatal("Initializing parser failed"); } // Run the parser group = parser.Run(group); if (Logger.HasErrors) { Logger.Fatal("Parsing C++ failed."); } else { Logger.Message("Parsing C++ finished"); } // Print statistics PrintStatistics(parser); return(group); }
private GccXmlDoc ParseHeaders(CastXml castXml) { StreamReader xmlReader = null; const string progressMessage = "Parsing C++ headers starts, please wait..."; try { Logger.Progress(15, progressMessage); var configRootHeader = Path.Combine(IntermediateOutputPath, Config.Id + ".h"); xmlReader = castXml.Process(configRootHeader); if (xmlReader != null) { return(GccXmlDoc.Load(xmlReader)); } Logger.Progress(30, progressMessage); } catch (Exception ex) { Logger.Error(null, "Unexpected error", ex); } finally { xmlReader?.Dispose(); Logger.Message("Parsing headers is finished."); } return(null); }
static void Main(string[] args) { var consoleLogger = new ConsoleLogger(); var logger = new Logger(consoleLogger, consoleLogger); string executablePath = null; // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // executablePath = Path.GetFullPath("../../../../../bin/CastXML/bin/castxml.exe"); var castXml = new CastXml(logger, new IncludeDirectoryResolver(logger), executablePath); var cppParser = new CppParser(logger, castXml); var config = new ContextConfig() { Id = Path.GetFullPath("test.c"), Process = new string[] { Path.GetFullPath("test.c"), // Path.GetFullPath("test.h"), }.ToList(), Include = new string[] { Path.GetFullPath("test.h"), }.ToList(), Macros = new Dictionary <string, string>() { { "ARRSIZE", "42 * 3" } } }; cppParser.Initialize(config); var module = cppParser.Run(new CppModel.CppModule()); foreach (var inc in module.Includes) { Console.WriteLine(inc.Name); foreach (var struct_ in inc.Structs) { Console.WriteLine(" " + struct_.Name + " " + struct_.Size); foreach (var field in struct_.Fields) { Console.WriteLine(" " + field.Name + " " + field.Offset); } } } Console.WriteLine(JsonConvert.SerializeObject(module, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, TypeNameHandling = TypeNameHandling.All })); foreach (var f in typeof(CastXml).Assembly.GetManifestResourceNames()) { Console.WriteLine(f); } Console.WriteLine(module); Environment.Exit(module is null ? 1 : 0); }
/// <summary> /// Run CodeGenerator /// </summary> public GccXmlDoc Run() { GccXmlDoc doc = null; Logger.Progress(0, "Starting code generation..."); try { var consumerConfig = new ConfigFile { Id = ConsumerBindMappingConfigId }; var filesWithIncludes = Config.GetFilesWithIncludes(); var configsWithIncludes = new HashSet <ConfigFile>(); // Add the root configsWithIncludes.Add(Config); foreach (var config in Config.ConfigFilesLoaded) { if (filesWithIncludes.Contains(config.Id)) { configsWithIncludes.Add(config); } } GenerateHeaders(configsWithIncludes, consumerConfig); if (Logger.HasErrors) { Logger.Fatal("Failed to generate C++ headers."); } var resolver = new IncludeDirectoryResolver(Logger); resolver.Configure(Config); var castXml = new CastXml(Logger, resolver, CastXmlExecutablePath) { OutputPath = IntermediateOutputPath, }; doc = ParseHeaders(castXml); if (Logger.HasErrors) { Logger.Fatal("Header parsing failed"); } OutputExternDefinition(doc); } finally { Logger.Progress(100, "Finished"); } return(doc); }
protected override bool Execute(ConfigFile config) { var configsWithExtensions = new HashSet <string>(); foreach (var file in ExtensionHeaders) { configsWithExtensions.Add(file.GetMetadata("ConfigId")); } var updatedConfigs = new HashSet <ConfigFile>(); foreach (var cfg in config.ConfigFilesLoaded) { if (UpdatedConfigs.Any(updated => updated.GetMetadata("Id") == cfg.Id)) { updatedConfigs.Add(cfg); } } var resolver = new IncludeDirectoryResolver(SharpGenLogger); resolver.Configure(config); var castXml = new CastXml(SharpGenLogger, resolver, CastXmlExecutablePath, CastXmlArguments) { OutputPath = OutputPath }; var macroManager = new MacroManager(castXml); var cppExtensionGenerator = new CppExtensionHeaderGenerator(macroManager); var module = cppExtensionGenerator.GenerateExtensionHeaders(config, OutputPath, configsWithExtensions, updatedConfigs); ReferencedHeaders = macroManager.IncludedFiles.Select(file => new TaskItem(file)).ToArray(); if (SharpGenLogger.HasErrors) { return(false); } module.Write(PartialCppModuleCache.ItemSpec); return(!SharpGenLogger.HasErrors); }
protected CppModule ParseCpp(ConfigFile config, string[] additionalArguments = null) { var loaded = ConfigFile.Load(config, new string[0], Logger); var(filesWithIncludes, filesWithExtensionHeaders) = loaded.GetFilesWithIncludesAndExtensionHeaders(); var configsWithIncludes = new HashSet <ConfigFile>(); foreach (var cfg in loaded.ConfigFilesLoaded) { if (filesWithIncludes.Contains(cfg.Id)) { configsWithIncludes.Add(cfg); } } var cppHeaderGenerator = new CppHeaderGenerator(Logger, true, TestDirectory.FullName); var(updated, _) = cppHeaderGenerator.GenerateCppHeaders(loaded, configsWithIncludes, filesWithExtensionHeaders); var resolver = new IncludeDirectoryResolver(Logger); resolver.Configure(loaded); var castXml = new CastXml(Logger, resolver, CastXmlExecutablePath, additionalArguments ?? Array.Empty <string>()) { OutputPath = TestDirectory.FullName }; var extensionGenerator = new CppExtensionHeaderGenerator(new MacroManager(castXml)); var skeleton = extensionGenerator.GenerateExtensionHeaders(loaded, TestDirectory.FullName, filesWithExtensionHeaders, updated); var parser = new CppParser(Logger, castXml) { OutputPath = TestDirectory.FullName }; parser.Initialize(loaded); return(parser.Run(skeleton)); }
protected override bool Execute(ConfigFile config) { var resolver = new IncludeDirectoryResolver(SharpGenLogger); resolver.Configure(config); var castXml = new CastXml(SharpGenLogger, resolver, CastXmlExecutablePath) { OutputPath = OutputPath }; // Run the parser var parser = new CppParser(SharpGenLogger, castXml) { OutputPath = OutputPath }; parser.Initialize(config); if (SharpGenLogger.HasErrors) { return(false); } var module = CppModule.Read(PartialCppModuleCache.ItemSpec); // Run the parser var group = parser.Run(module, CastXmlArguments ?? Array.Empty <string>()); if (SharpGenLogger.HasErrors) { return(false); } group.Write(ParsedCppModule.ItemSpec); return(true); }
static void Main(string[] args) { var consoleLogger = new ConsoleLogger(); var logger = new Logger(consoleLogger, null); ConfigFile config = new ConfigFile() { Id = "ChakraCore", IncludeDirs = { new IncludeDirRule { Path = @"C:\Projects\chakracore\lib\Jsrt\" } }, Includes = { new IncludeRule { Attach = true, File = @"C:\Projects\chakracore\lib\Jsrt\ChakraCore.h", Namespace = "ChakraCore", }, new IncludeRule { Attach = true, File = @"C:\Projects\chakracore\lib\Jsrt\ChakraCommon.h", Namespace = "ChakraCommon", }, new IncludeRule { Attach = true, File = @"C:\Projects\chakracore\lib\Jsrt\ChakraDebug.h", Namespace = "ChakraCommon", }, }, IgnoreFunctions = { "^JsTTD.*" }, TypeMap = { new TypeMapRule { From = "void*", To = "IntPtr" }, new TypeMapRule { From = "void**", To = "IntPtr*" }, new TypeMapRule { From = "BYTE*", To = "byte[]" }, new TypeMapRule { From = "char", FromDirection = ParameterDirection.Out, To = "char*", ToDirection = ParameterDirection.In }, new TypeMapRule { From = "char**", To = "string" }, new TypeMapRule { From = "uint16_t", FromDirection = ParameterDirection.Out, To = "uint16_t*", ToDirection = ParameterDirection.In }, new TypeMapRule { From = "uint16_t**", To = "string" }, new TypeMapRule { From = "unsigned int", To = "uint" }, new TypeMapRule { From = "unsigned int*", To = "uint*" }, new TypeMapRule { From = "short unsigned int", To = "ushort" }, new TypeMapRule { From = "JsValueRef*", To = "JsValueRef[]" }, new TypeMapRule { From = "JsWeakRef", FromDirection = ParameterDirection.Out, To = "IntPtr" }, new TypeMapRule { From = "BYTE", FromDirection = ParameterDirection.Out, To = "byte[]", ToDirection = ParameterDirection.In }, new TypeMapRule { From = "ChakraBytePtr", To = "IntPtr" }, new TypeMapRule { From = "wchar_t**", FromDirection = ParameterDirection.In, To = "string" }, new TypeMapRule { From = "wchar_t**", FromDirection = ParameterDirection.Out, To = "IntPtr" }, new TypeMapRule { From = "JsSharedArrayBufferContentHandle", FromDirection = ParameterDirection.Out, To = "IntPtr" }, }, ExportExtensions = { new ExportExtensionRule { FunctionName = "JsCreateStringUtf16", Extensions = { new XAttribute("dllImportEx", ", CharSet = CharSet.Unicode") } }, new ExportExtensionRule { FunctionName = "JsCopyString", Extensions = { new XAttribute("dllImportEx", ", CharSet = CharSet.Ansi") } } } }; var outputDi = Directory.CreateDirectory("../output"); var chakraSharpDir = Directory.CreateDirectory("../output/ChakraSharp"); var intermediateOutputDir = Directory.CreateDirectory("../output/temp"); var castXmlPath = @"C:\Projects\ChakraCoreCastXml\lib\castxml\bin\castxml.exe"; if (!File.Exists(castXmlPath)) { throw new InvalidOperationException("Unable to locate CastXml at " + castXmlPath); } var resolver = new IncludeDirectoryResolver(logger); resolver.Configure(config); var castXml = new CastXml(logger, resolver, castXmlPath) { OutputPath = "", }; var codeGenApp = new ChakraExternGenerator(logger) { CastXmlExecutablePath = castXmlPath, Config = config, OutputDirectory = @"C:\Projects\BaristaCore", IntermediateOutputPath = intermediateOutputDir.FullName, }; codeGenApp.Init(); codeGenApp.Run(); }
private CppModule GenerateExtensionHeaders(IReadOnlyCollection <string> filesWithExtensions, IReadOnlyCollection <ConfigFile> updatedConfigs, CastXml castXml) { Logger.Progress(10, "Generating C++ extensions from macros"); var cppExtensionHeaderGenerator = new CppExtensionHeaderGenerator(new MacroManager(castXml)); var group = cppExtensionHeaderGenerator.GenerateExtensionHeaders(Config, IntermediateOutputPath, filesWithExtensions, updatedConfigs); return(group); }
/// <summary> /// Run CodeGenerator /// </summary> public void Run() { Logger.Progress(0, "Starting code generation..."); try { var consumerConfig = new ConfigFile { Id = ConsumerBindMappingConfigId }; var(filesWithIncludes, filesWithExtensions) = Config.GetFilesWithIncludesAndExtensionHeaders(); var configsWithIncludes = new HashSet <ConfigFile>(); foreach (var config in Config.ConfigFilesLoaded) { if (filesWithIncludes.Contains(config.Id)) { configsWithIncludes.Add(config); } } var sdkResolver = new SdkResolver(Logger); foreach (var config in Config.ConfigFilesLoaded) { foreach (var sdk in config.Sdks) { config.IncludeDirs.AddRange(sdkResolver.ResolveIncludeDirsForSdk(sdk)); } } var cppHeadersUpdated = GenerateHeaders(filesWithExtensions, configsWithIncludes, consumerConfig); if (Logger.HasErrors) { Logger.Fatal("Failed to generate C++ headers."); } CppModule group; var groupFileName = $"{Config.Id}-out.xml"; if (cppHeadersUpdated.Count != 0) { var resolver = new IncludeDirectoryResolver(Logger); resolver.Configure(Config); var castXml = new CastXml(Logger, resolver, CastXmlExecutablePath, Array.Empty <string>()) { OutputPath = IntermediateOutputPath, }; group = GenerateExtensionHeaders(filesWithExtensions, cppHeadersUpdated, castXml); group = ParseCpp(castXml, group); if (IsGeneratingDoc) { ApplyDocumentation(DocumentationCache, group); } } else { Logger.Progress(10, "Config files unchanged. Read previous C++ parsing..."); if (File.Exists(Path.Combine(IntermediateOutputPath, groupFileName))) { group = CppModule.Read(Path.Combine(IntermediateOutputPath, groupFileName)); } else { group = new CppModule(); } } // Save back the C++ parsed includes group.Write(Path.Combine(IntermediateOutputPath, groupFileName)); Config.ExpandDynamicVariables(Logger, group); var(docAggregator, asm) = ExecuteMappings(group, consumerConfig); asm.Write(Path.Combine(IntermediateOutputPath, "Assembly.xml")); asm = CsAssembly.Read(Path.Combine(IntermediateOutputPath, "Assembly.xml")); GenerateConfigForConsumers(consumerConfig); GenerateCode(docAggregator, asm, new ExternalDocCommentsReader(ExternalDocumentation)); if (Logger.HasErrors) { Logger.Fatal("Code generation failed"); } // Update Checkfile for assembly File.WriteAllText(_assemblyCheckFile, ""); File.SetLastWriteTime(_assemblyCheckFile, _assemblyDatetime); // Update Checkfile for all config files File.WriteAllText(_allConfigCheck, ""); File.SetLastWriteTime(_allConfigCheck, DateTime.Now); } finally { Logger.Progress(100, "Finished"); } }