aboutsummaryrefslogtreecommitdiff
path: root/src/internal/WixBuildTools.MsgGen/MsgGen.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/WixBuildTools.MsgGen/MsgGen.cs')
-rw-r--r--src/internal/WixBuildTools.MsgGen/MsgGen.cs261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/internal/WixBuildTools.MsgGen/MsgGen.cs b/src/internal/WixBuildTools.MsgGen/MsgGen.cs
new file mode 100644
index 00000000..ff4a4a90
--- /dev/null
+++ b/src/internal/WixBuildTools.MsgGen/MsgGen.cs
@@ -0,0 +1,261 @@
1// 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.
2
3namespace WixBuildTools.MsgGen
4{
5 using Microsoft.CSharp;
6 using System;
7 using System.CodeDom;
8 using System.CodeDom.Compiler;
9 using System.Collections;
10 using System.IO;
11 using System.Reflection;
12 using System.Resources;
13 using System.Runtime.InteropServices;
14 using System.Xml;
15 using System.Xml.Schema;
16
17 /// <summary>
18 /// The main entry point for MsgGen.
19 /// </summary>
20 public class MsgGen
21 {
22 /// <summary>
23 /// The main entry point for MsgGen.
24 /// </summary>
25 /// <param name="args">Commandline arguments for the application.</param>
26 /// <returns>Returns the application error code.</returns>
27 [STAThread]
28 public static int Main(string[] args)
29 {
30 try
31 {
32 MsgGenMain msgGen = new MsgGenMain(args);
33 }
34 catch (Exception e)
35 {
36 Console.WriteLine("MsgGen.exe : fatal error MSGG0000: {0}\r\n\r\nStack Trace:\r\n{1}", e.Message, e.StackTrace);
37 if (e is NullReferenceException || e is SEHException)
38 {
39 throw;
40 }
41 return 2;
42 }
43
44 return 0;
45 }
46
47 /// <summary>
48 /// Main class for MsgGen.
49 /// </summary>
50 private class MsgGenMain
51 {
52 private bool showLogo;
53 private bool showHelp;
54
55 private string sourceFile;
56 private string destClassFile;
57 private string destResourcesFile;
58
59 /// <summary>
60 /// Main method for the MsgGen application within the MsgGenMain class.
61 /// </summary>
62 /// <param name="args">Commandline arguments to the application.</param>
63 public MsgGenMain(string[] args)
64 {
65 this.showLogo = true;
66 this.showHelp = false;
67
68 this.sourceFile = null;
69 this.destClassFile = null;
70 this.destResourcesFile = null;
71
72 // parse the command line
73 this.ParseCommandLine(args);
74
75 if (null == this.sourceFile || null == this.destClassFile)
76 {
77 this.showHelp = true;
78 }
79 if (null == this.destResourcesFile)
80 {
81 this.destResourcesFile = Path.ChangeExtension(this.destClassFile, ".resources");
82 }
83
84 // get the assemblies
85 Assembly msgGenAssembly = Assembly.GetExecutingAssembly();
86
87 if (this.showLogo)
88 {
89 Console.WriteLine("Microsoft (R) Message Generation Tool version {0}", msgGenAssembly.GetName().Version.ToString());
90 Console.WriteLine("Copyright (C) Microsoft Corporation 2004. All rights reserved.");
91 Console.WriteLine();
92 }
93 if (this.showHelp)
94 {
95 Console.WriteLine(" usage: MsgGen.exe [-?] [-nologo] sourceFile destClassFile [destResourcesFile]");
96 Console.WriteLine();
97 Console.WriteLine(" -? this help information");
98 Console.WriteLine();
99 Console.WriteLine("For more information see: http://wix.sourceforge.net");
100 return; // exit
101 }
102
103 // load the schema
104 XmlReader reader = null;
105 XmlSchemaCollection schemaCollection = null;
106 try
107 {
108 reader = new XmlTextReader(msgGenAssembly.GetManifestResourceStream("WixBuildTools.MsgGen.Xsd.messages.xsd"));
109 schemaCollection = new XmlSchemaCollection();
110 schemaCollection.Add("http://schemas.microsoft.com/genmsgs/2004/07/messages", reader);
111 }
112 finally
113 {
114 reader.Close();
115 }
116
117 // load the source file and process it
118 using (StreamReader sr = new StreamReader(this.sourceFile))
119 {
120 XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.None);
121 XmlValidatingReader validatingReader = new XmlValidatingReader(sr.BaseStream, XmlNodeType.Document, context);
122 validatingReader.Schemas.Add(schemaCollection);
123
124 XmlDocument errorsDoc = new XmlDocument();
125 errorsDoc.Load(validatingReader);
126
127 CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
128
129 using (ResourceWriter resourceWriter = new ResourceWriter(this.destResourcesFile))
130 {
131 GenerateMessageFiles.Generate(errorsDoc, codeCompileUnit, resourceWriter);
132
133 GenerateCSharpCode(codeCompileUnit, this.destClassFile);
134 }
135 }
136 }
137
138 /// <summary>
139 /// Generate the actual C# code.
140 /// </summary>
141 /// <param name="codeCompileUnit">The code DOM.</param>
142 /// <param name="destClassFile">Destination C# source file.</param>
143 public static void GenerateCSharpCode(CodeCompileUnit codeCompileUnit, string destClassFile)
144 {
145 // generate the code with the C# code provider
146 CSharpCodeProvider provider = new CSharpCodeProvider();
147
148 // obtain an ICodeGenerator from the CodeDomProvider class
149 ICodeGenerator gen = provider.CreateGenerator();
150
151 // create a TextWriter to a StreamWriter to the output file
152 using (StreamWriter sw = new StreamWriter(destClassFile))
153 {
154 using (IndentedTextWriter tw = new IndentedTextWriter(sw, " "))
155 {
156 CodeGeneratorOptions options = new CodeGeneratorOptions();
157
158 // code generation options
159 options.BlankLinesBetweenMembers = true;
160 options.BracingStyle = "C";
161
162 // generate source code using the code generator
163 gen.GenerateCodeFromCompileUnit(codeCompileUnit, tw, options);
164 }
165 }
166 }
167
168 /// <summary>
169 /// Parse the commandline arguments.
170 /// </summary>
171 /// <param name="args">Commandline arguments.</param>
172 private void ParseCommandLine(string[] args)
173 {
174 for (int i = 0; i < args.Length; ++i)
175 {
176 string arg = args[i];
177 if (null == arg || "" == arg) // skip blank arguments
178 {
179 continue;
180 }
181
182 if ('-' == arg[0] || '/' == arg[0])
183 {
184 string parameter = arg.Substring(1);
185 if ("nologo" == parameter)
186 {
187 this.showLogo = false;
188 }
189 else if ("?" == parameter || "help" == parameter)
190 {
191 this.showHelp = true;
192 }
193 }
194 else if ('@' == arg[0])
195 {
196 using (StreamReader reader = new StreamReader(arg.Substring(1)))
197 {
198 string line;
199 ArrayList newArgs = new ArrayList();
200
201 while (null != (line = reader.ReadLine()))
202 {
203 string newArg = "";
204 bool betweenQuotes = false;
205 for (int j = 0; j < line.Length; ++j)
206 {
207 // skip whitespace
208 if (!betweenQuotes && (' ' == line[j] || '\t' == line[j]))
209 {
210 if ("" != newArg)
211 {
212 newArgs.Add(newArg);
213 newArg = null;
214 }
215
216 continue;
217 }
218
219 // if we're escaping a quote
220 if ('\\' == line[j] && '"' == line[j])
221 {
222 ++j;
223 }
224 else if ('"' == line[j]) // if we've hit a new quote
225 {
226 betweenQuotes = !betweenQuotes;
227 continue;
228 }
229
230 newArg = String.Concat(newArg, line[j]);
231 }
232 if ("" != newArg)
233 {
234 newArgs.Add(newArg);
235 }
236 }
237 string[] ar = (string[])newArgs.ToArray(typeof(string));
238 this.ParseCommandLine(ar);
239 }
240 }
241 else if (null == this.sourceFile)
242 {
243 this.sourceFile = arg;
244 }
245 else if (null == this.destClassFile)
246 {
247 this.destClassFile = arg;
248 }
249 else if (null == this.destResourcesFile)
250 {
251 this.destResourcesFile = arg;
252 }
253 else
254 {
255 throw new ArgumentException(String.Format("Unknown argument '{0}'.", arg));
256 }
257 }
258 }
259 }
260 }
261}