From 4418bd52f1fca52a0d8d5f5b60abd2fdfc7146bd Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 15 Aug 2017 01:31:51 -0700 Subject: Migrate MsgGen --- src/WixBuildTools.MsgGen/MsgGen.cs | 261 +++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 src/WixBuildTools.MsgGen/MsgGen.cs (limited to 'src/WixBuildTools.MsgGen/MsgGen.cs') diff --git a/src/WixBuildTools.MsgGen/MsgGen.cs b/src/WixBuildTools.MsgGen/MsgGen.cs new file mode 100644 index 00000000..ff4a4a90 --- /dev/null +++ b/src/WixBuildTools.MsgGen/MsgGen.cs @@ -0,0 +1,261 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixBuildTools.MsgGen +{ + using Microsoft.CSharp; + using System; + using System.CodeDom; + using System.CodeDom.Compiler; + using System.Collections; + using System.IO; + using System.Reflection; + using System.Resources; + using System.Runtime.InteropServices; + using System.Xml; + using System.Xml.Schema; + + /// + /// The main entry point for MsgGen. + /// + public class MsgGen + { + /// + /// The main entry point for MsgGen. + /// + /// Commandline arguments for the application. + /// Returns the application error code. + [STAThread] + public static int Main(string[] args) + { + try + { + MsgGenMain msgGen = new MsgGenMain(args); + } + catch (Exception e) + { + Console.WriteLine("MsgGen.exe : fatal error MSGG0000: {0}\r\n\r\nStack Trace:\r\n{1}", e.Message, e.StackTrace); + if (e is NullReferenceException || e is SEHException) + { + throw; + } + return 2; + } + + return 0; + } + + /// + /// Main class for MsgGen. + /// + private class MsgGenMain + { + private bool showLogo; + private bool showHelp; + + private string sourceFile; + private string destClassFile; + private string destResourcesFile; + + /// + /// Main method for the MsgGen application within the MsgGenMain class. + /// + /// Commandline arguments to the application. + public MsgGenMain(string[] args) + { + this.showLogo = true; + this.showHelp = false; + + this.sourceFile = null; + this.destClassFile = null; + this.destResourcesFile = null; + + // parse the command line + this.ParseCommandLine(args); + + if (null == this.sourceFile || null == this.destClassFile) + { + this.showHelp = true; + } + if (null == this.destResourcesFile) + { + this.destResourcesFile = Path.ChangeExtension(this.destClassFile, ".resources"); + } + + // get the assemblies + Assembly msgGenAssembly = Assembly.GetExecutingAssembly(); + + if (this.showLogo) + { + Console.WriteLine("Microsoft (R) Message Generation Tool version {0}", msgGenAssembly.GetName().Version.ToString()); + Console.WriteLine("Copyright (C) Microsoft Corporation 2004. All rights reserved."); + Console.WriteLine(); + } + if (this.showHelp) + { + Console.WriteLine(" usage: MsgGen.exe [-?] [-nologo] sourceFile destClassFile [destResourcesFile]"); + Console.WriteLine(); + Console.WriteLine(" -? this help information"); + Console.WriteLine(); + Console.WriteLine("For more information see: http://wix.sourceforge.net"); + return; // exit + } + + // load the schema + XmlReader reader = null; + XmlSchemaCollection schemaCollection = null; + try + { + reader = new XmlTextReader(msgGenAssembly.GetManifestResourceStream("WixBuildTools.MsgGen.Xsd.messages.xsd")); + schemaCollection = new XmlSchemaCollection(); + schemaCollection.Add("http://schemas.microsoft.com/genmsgs/2004/07/messages", reader); + } + finally + { + reader.Close(); + } + + // load the source file and process it + using (StreamReader sr = new StreamReader(this.sourceFile)) + { + XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.None); + XmlValidatingReader validatingReader = new XmlValidatingReader(sr.BaseStream, XmlNodeType.Document, context); + validatingReader.Schemas.Add(schemaCollection); + + XmlDocument errorsDoc = new XmlDocument(); + errorsDoc.Load(validatingReader); + + CodeCompileUnit codeCompileUnit = new CodeCompileUnit(); + + using (ResourceWriter resourceWriter = new ResourceWriter(this.destResourcesFile)) + { + GenerateMessageFiles.Generate(errorsDoc, codeCompileUnit, resourceWriter); + + GenerateCSharpCode(codeCompileUnit, this.destClassFile); + } + } + } + + /// + /// Generate the actual C# code. + /// + /// The code DOM. + /// Destination C# source file. + public static void GenerateCSharpCode(CodeCompileUnit codeCompileUnit, string destClassFile) + { + // generate the code with the C# code provider + CSharpCodeProvider provider = new CSharpCodeProvider(); + + // obtain an ICodeGenerator from the CodeDomProvider class + ICodeGenerator gen = provider.CreateGenerator(); + + // create a TextWriter to a StreamWriter to the output file + using (StreamWriter sw = new StreamWriter(destClassFile)) + { + using (IndentedTextWriter tw = new IndentedTextWriter(sw, " ")) + { + CodeGeneratorOptions options = new CodeGeneratorOptions(); + + // code generation options + options.BlankLinesBetweenMembers = true; + options.BracingStyle = "C"; + + // generate source code using the code generator + gen.GenerateCodeFromCompileUnit(codeCompileUnit, tw, options); + } + } + } + + /// + /// Parse the commandline arguments. + /// + /// Commandline arguments. + private void ParseCommandLine(string[] args) + { + for (int i = 0; i < args.Length; ++i) + { + string arg = args[i]; + if (null == arg || "" == arg) // skip blank arguments + { + continue; + } + + if ('-' == arg[0] || '/' == arg[0]) + { + string parameter = arg.Substring(1); + if ("nologo" == parameter) + { + this.showLogo = false; + } + else if ("?" == parameter || "help" == parameter) + { + this.showHelp = true; + } + } + else if ('@' == arg[0]) + { + using (StreamReader reader = new StreamReader(arg.Substring(1))) + { + string line; + ArrayList newArgs = new ArrayList(); + + while (null != (line = reader.ReadLine())) + { + string newArg = ""; + bool betweenQuotes = false; + for (int j = 0; j < line.Length; ++j) + { + // skip whitespace + if (!betweenQuotes && (' ' == line[j] || '\t' == line[j])) + { + if ("" != newArg) + { + newArgs.Add(newArg); + newArg = null; + } + + continue; + } + + // if we're escaping a quote + if ('\\' == line[j] && '"' == line[j]) + { + ++j; + } + else if ('"' == line[j]) // if we've hit a new quote + { + betweenQuotes = !betweenQuotes; + continue; + } + + newArg = String.Concat(newArg, line[j]); + } + if ("" != newArg) + { + newArgs.Add(newArg); + } + } + string[] ar = (string[])newArgs.ToArray(typeof(string)); + this.ParseCommandLine(ar); + } + } + else if (null == this.sourceFile) + { + this.sourceFile = arg; + } + else if (null == this.destClassFile) + { + this.destClassFile = arg; + } + else if (null == this.destResourcesFile) + { + this.destResourcesFile = arg; + } + else + { + throw new ArgumentException(String.Format("Unknown argument '{0}'.", arg)); + } + } + } + } + } +} -- cgit v1.2.3-55-g6feb