Add color support for errors/warnings etc.
[mcs.git] / tools / xbuild / Parameters.cs
blob1f36902f43d89b368ddcf76dfd2a019403dec550
1 //
2 // Parameters.cs: Class that contains information about command line parameters
3 //
4 // Author:
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2005 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #if NET_2_0
30 using System;
31 using System.IO;
32 using System.Collections;
33 using System.Text;
34 using System.Reflection;
35 using Microsoft.Build.BuildEngine;
36 using Microsoft.Build.Framework;
37 using Microsoft.Build.Utilities;
39 namespace Mono.XBuild.CommandLine {
40 public class Parameters {
42 string consoleLoggerParameters;
43 bool displayHelp;
44 bool displayVersion;
45 IList flatArguments;
46 IList loggers;
47 LoggerVerbosity loggerVerbosity;
48 bool noConsoleLogger;
49 bool noLogo;
50 string projectFile;
51 BuildPropertyGroup properties;
52 IList remainingArguments;
53 Hashtable responseFiles;
54 string[] targets;
55 bool validate;
56 string validationSchema;
58 string responseFile;
60 public Parameters (string binPath)
62 consoleLoggerParameters = "";
63 displayHelp = false;
64 displayVersion = true;
65 loggers = new ArrayList ();
66 loggerVerbosity = LoggerVerbosity.Normal;
67 noConsoleLogger = false;
68 noLogo = false;
69 properties = new BuildPropertyGroup ();
70 targets = new string [0];
72 responseFile = Path.Combine (
73 Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location),
74 "xbuild.rsp");
77 public void ParseArguments (string[] args)
79 bool autoResponse = true;
80 flatArguments = new ArrayList ();
81 remainingArguments = new ArrayList ();
82 responseFiles = new Hashtable ();
83 foreach (string s in args) {
84 if (s.StartsWith ("/noautoresponse") || s.StartsWith ("/noautorsp")) {
85 autoResponse = false;
86 continue;
88 if (s [0] != '@') {
89 flatArguments.Add (s);
90 continue;
92 string responseFilename = Path.GetFullPath (s.Substring (1));
93 if (responseFiles.ContainsKey (responseFilename))
94 ErrorUtilities.ReportError (1, String.Format ("We already have {0} file.", responseFilename));
95 responseFiles [responseFilename] = responseFilename;
96 LoadResponseFile (responseFilename);
98 if (autoResponse == true) {
99 // FIXME: we do not allow nested auto response file
100 LoadResponseFile (responseFile);
102 foreach (string s in flatArguments) {
103 if (s [0] != '/' || !ParseFlatArgument (s))
104 remainingArguments.Add (s);
106 if (remainingArguments.Count == 0) {
107 string[] sln_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*.sln");
108 string[] proj_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*proj");
110 if (sln_files.Length == 0 && proj_files.Length == 0)
111 ErrorUtilities.ReportError (3, "Please specify the project or solution file " +
112 "to build, as none was found in the current directory.");
114 if (sln_files.Length + proj_files.Length > 1)
115 ErrorUtilities.ReportError (5, "Please specify the project or solution file " +
116 "to build, as more than one solution or project file was found " +
117 "in the current directory");
119 if (sln_files.Length == 1)
120 projectFile = sln_files [0];
121 else
122 projectFile = proj_files [0];
123 } else if (remainingArguments.Count == 1) {
124 projectFile = (string) remainingArguments [0];
125 } else {
126 ErrorUtilities.ReportError (4, "Too many project files specified");
130 void LoadResponseFile (string filename)
132 StreamReader sr = null;
133 string line;
134 try {
135 sr = new StreamReader (filename);
136 StringBuilder sb = new StringBuilder ();
138 while ((line = sr.ReadLine ()) != null) {
139 int t = line.Length;
141 for (int i = 0; i < t; i++) {
142 char c = line [i];
144 if (c == '#')
145 // comment, ignore rest of the line
146 break;
148 if (c == '"' || c == '\'') {
149 char end = c;
151 for (i++; i < t; i++) {
152 c = line [i];
154 if (c == end)
155 break;
156 sb.Append (c);
158 } else if (c == ' ') {
159 if (sb.Length > 0) {
160 flatArguments.Add (sb.ToString ());
161 sb.Length = 0;
163 } else
164 sb.Append (c);
166 if (sb.Length > 0){
167 flatArguments.Add (sb.ToString ());
168 sb.Length = 0;
171 } catch (Exception) {
172 // FIXME: we lose exception message
173 ErrorUtilities.ReportError (2, "Error during loading response file.");
174 } finally {
175 if (sr != null)
176 sr.Close ();
180 private bool ParseFlatArgument (string s)
182 switch (s) {
183 case "/help":
184 case "/h":
185 case "/?":
186 ErrorUtilities.ShowUsage ();
187 break;
188 case "/nologo":
189 noLogo = true;
190 break;
191 case "/version":
192 case "/ver":
193 ErrorUtilities.ShowVersion (true);
194 break;
195 case "/noconsolelogger":
196 case "/noconlog":
197 noConsoleLogger = true;
198 break;
199 case "/validate":
200 case "/val":
201 validate = true;
202 break;
203 default:
204 if (s.StartsWith ("/target:") || s.StartsWith ("/t:")) {
205 ProcessTarget (s);
206 } else if (s.StartsWith ("/property:") || s.StartsWith ("/p:")) {
207 if (!ProcessProperty (s))
208 return false;
209 } else if (s.StartsWith ("/logger:") || s.StartsWith ("/l:")) {
210 ProcessLogger (s);
211 } else if (s.StartsWith ("/verbosity:") || s.StartsWith ("/v:")) {
212 ProcessVerbosity (s);
213 } else if (s.StartsWith ("/consoleloggerparameters:") || s.StartsWith ("/clp:")) {
214 ProcessConsoleLoggerParameters (s);
215 } else if (s.StartsWith ("/validate:") || s.StartsWith ("/val:")) {
216 ProcessValidate (s);
217 } else
218 return false;
219 break;
222 return true;
225 internal void ProcessTarget (string s)
227 string[] temp = s.Split (':');
228 targets = temp [1].Split (';');
231 internal bool ProcessProperty (string s)
233 string[] parameter, splittedProperties, property;
234 parameter = s.Split (':');
235 if (parameter.Length != 2) {
236 ErrorUtilities.ReportError (5, "Property name and value expected as /p:<prop name>=<prop value>");
237 return false;
240 splittedProperties = parameter [1].Split (';');
241 foreach (string st in splittedProperties) {
242 if (st.IndexOf ('=') < 0) {
243 ErrorUtilities.ReportError (5,
244 "Invalid syntax. Property name and value expected as " +
245 "<prop name>=[<prop value>]");
246 return false;
248 property = st.Split ('=');
249 properties.SetProperty (property [0], property.Length == 2 ? property [1] : "");
252 return true;
255 internal void ProcessLogger (string s)
257 loggers.Add (new LoggerInfo (s));
260 internal void ProcessVerbosity (string s)
262 string[] temp = s.Split (':');
263 switch (temp [1]) {
264 case "q":
265 case "quiet":
266 loggerVerbosity = LoggerVerbosity.Quiet;
267 break;
268 case "m":
269 case "minimal":
270 loggerVerbosity = LoggerVerbosity.Minimal;
271 break;
272 case "n":
273 case "normal":
274 loggerVerbosity = LoggerVerbosity.Normal;
275 break;
276 case "d":
277 case "detailed":
278 loggerVerbosity = LoggerVerbosity.Detailed;
279 break;
280 case "diag":
281 case "diagnostic":
282 loggerVerbosity = LoggerVerbosity.Diagnostic;
283 break;
287 internal void ProcessConsoleLoggerParameters (string s)
289 consoleLoggerParameters = s;
292 internal void ProcessValidate (string s)
294 string[] temp;
295 validate = true;
296 temp = s.Split (':');
297 validationSchema = temp [1];
299 public bool DisplayHelp {
300 get { return displayHelp; }
303 public bool NoLogo {
304 get { return noLogo; }
307 public bool DisplayVersion {
308 get { return displayVersion; }
311 public string ProjectFile {
312 get { return projectFile; }
315 public string[] Targets {
316 get { return targets; }
319 public BuildPropertyGroup Properties {
320 get { return properties; }
323 public IList Loggers {
324 get { return loggers; }
327 public LoggerVerbosity LoggerVerbosity {
328 get { return loggerVerbosity; }
331 public string ConsoleLoggerParameters {
332 get { return consoleLoggerParameters; }
335 public bool NoConsoleLogger {
336 get { return noConsoleLogger; }
339 public bool Validate {
340 get { return validate; }
343 public string ValidationSchema {
344 get { return validationSchema; }
350 #endif