* Parameters.cs (.ctor): Use assembly's location to build
[mono.git] / mcs / tools / xbuild / Parameters.cs
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
28 #if NET_2_0
29
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;
38
39 namespace Mono.XBuild.CommandLine {
40         public class Parameters {
41         
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;
57                 
58                 string                  responseFile;
59         
60                 public Parameters (string binPath)
61                 {
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];
71                         
72                         responseFile = Path.Combine (
73                                         Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location),
74                                         "xbuild.rsp");
75                 }
76                 
77                 public void ParseArguments (string[] args)
78                 {
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;
87                                 }
88                                 if (s [0] != '@') {
89                                         flatArguments.Add (s);
90                                         continue;
91                                 }
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);
97                         }
98                         if (autoResponse == true) {
99                                 // FIXME: we do not allow nested auto response file
100                                 LoadResponseFile (responseFile);
101                         }
102                         foreach (string s in flatArguments) {
103                                 if (s [0] != '/' || !ParseFlatArgument (s))
104                                         remainingArguments.Add (s);
105                         }
106                         if (remainingArguments.Count == 0) {
107                                 string[] files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*.??proj");
108                                 if (files.Length > 0)
109                                         projectFile = files [0];
110                                 else
111                                         ErrorUtilities.ReportError (3, "No .proj file specified and no found in current directory.");
112                         } else if (remainingArguments.Count == 1) {
113                                 projectFile = (string) remainingArguments [0];
114                         } else {
115                                 ErrorUtilities.ReportError (4, "Too many project files specified");
116                         }
117                 }
118                 
119                 void LoadResponseFile (string filename)
120                 {
121                         StreamReader sr = null;
122                         string line;
123                         try {
124                                 sr = new StreamReader (filename);
125                                 StringBuilder sb = new StringBuilder ();
126
127                                 while ((line = sr.ReadLine ()) != null) {
128                                         int t = line.Length;
129
130                                         for (int i = 0; i < t; i++) {
131                                                 char c = line [i];
132
133                                                 if (c == '#')
134                                                         // comment, ignore rest of the line
135                                                         break;
136
137                                                 if (c == '"' || c == '\'') {
138                                                         char end = c;
139
140                                                         for (i++; i < t; i++) {
141                                                                 c = line [i];
142
143                                                                 if (c == end)
144                                                                         break;
145                                                                 sb.Append (c);
146                                                         }
147                                                 } else if (c == ' ') {
148                                                         if (sb.Length > 0) {
149                                                                 flatArguments.Add (sb.ToString ());
150                                                                 sb.Length = 0;
151                                                         }
152                                                 } else
153                                                         sb.Append (c);
154                                         }
155                                         if (sb.Length > 0){
156                                                 flatArguments.Add (sb.ToString ());
157                                                 sb.Length = 0;
158                                         }
159                                 }
160                         } catch (Exception) {
161                                 // FIXME: we lose exception message
162                                 ErrorUtilities.ReportError (2, "Error during loading response file.");
163                         } finally {
164                                 if (sr != null)
165                                         sr.Close ();
166                         }
167                 }
168                 
169                 private bool ParseFlatArgument (string s)
170                 {
171                         switch (s) {
172                         case "/help":
173                         case "/h":
174                         case "/?":
175                                 ErrorUtilities.ShowUsage ();
176                                 break;
177                         case "/nologo":
178                                 noLogo = true;
179                                 break;
180                         case "/version":
181                         case "/ver":
182                                 ErrorUtilities.ShowVersion (true);
183                                 break;
184                         case "/noconsolelogger":
185                         case "/noconlog":
186                                 noConsoleLogger = true;
187                                 break;
188                         case "/validate":
189                         case "/val":
190                                 validate = true;
191                                 break;
192                         default:
193                                 if (s.StartsWith ("/target:") || s.StartsWith ("/t:")) {
194                                         ProcessTarget (s);
195                                 } else if (s.StartsWith ("/property:") || s.StartsWith ("/p:")) {
196                                         if (!ProcessProperty (s))
197                                                 return false;
198                                 } else  if (s.StartsWith ("/logger:") || s.StartsWith ("/l:")) {
199                                         ProcessLogger (s);
200                                 } else if (s.StartsWith ("/verbosity:") || s.StartsWith ("/v:")) {
201                                         ProcessVerbosity (s);
202                                 } else if (s.StartsWith ("/consoleloggerparameters:") || s.StartsWith ("/clp:")) {
203                                         ProcessConsoleLoggerParameters (s);
204                                 } else if (s.StartsWith ("/validate:") || s.StartsWith ("/val:")) {
205                                         ProcessValidate (s);
206                                 } else
207                                         return false;
208                                 break;
209                         }
210
211                         return true;
212                 }
213                 
214                 internal void ProcessTarget (string s)
215                 {
216                         string[] temp = s.Split (':');
217                         targets = temp [1].Split (';');
218                 }
219                 
220                 internal bool ProcessProperty (string s)
221                 {
222                         string[] parameter, splittedProperties, property;
223                         parameter = s.Split (':');
224                         if (parameter.Length != 2) {
225                                 ErrorUtilities.ReportError (5, "Property name and value expected as /p:<prop name>=<prop value>");
226                                 return false;
227                         }
228
229                         splittedProperties = parameter [1].Split (';');
230                         foreach (string st in splittedProperties) {
231                                 if (st.IndexOf ('=') < 0) {
232                                         ErrorUtilities.ReportError (5,
233                                                         "Invalid syntax. Property name and value expected as " +
234                                                         "<prop name>=[<prop value>]");
235                                         return false;
236                                 }
237                                 property = st.Split ('=');
238                                 properties.SetProperty (property [0], property.Length == 2 ? property [1] : "");
239                         }
240
241                         return true;
242                 }
243                 
244                 internal void ProcessLogger (string s)
245                 {
246                         loggers.Add (new LoggerInfo (s));
247                 }
248                 
249                 internal void ProcessVerbosity (string s)
250                 {
251                         string[] temp = s.Split (':');
252                         switch (temp [1]) {
253                         case "q":
254                         case "quiet":
255                                 loggerVerbosity = LoggerVerbosity.Quiet;
256                                 break;
257                         case "m":
258                         case "minimal":
259                                 loggerVerbosity = LoggerVerbosity.Minimal;
260                                 break;
261                         case "n":
262                         case "normal":
263                                 loggerVerbosity = LoggerVerbosity.Normal;
264                                 break;
265                         case "d":
266                         case "detailed":
267                                 loggerVerbosity = LoggerVerbosity.Detailed;
268                                 break;
269                         case "diag":
270                         case "diagnostic":
271                                 loggerVerbosity = LoggerVerbosity.Diagnostic;
272                                 break;
273                         }
274                 }
275                 
276                 internal void ProcessConsoleLoggerParameters (string s)
277                 {
278                         consoleLoggerParameters = s; 
279                 }
280                 
281                 internal void ProcessValidate (string s)
282                 {
283                         string[] temp;
284                         validate = true;
285                         temp = s.Split (':');
286                         validationSchema = temp [1];
287                 }
288                 public bool DisplayHelp {
289                         get { return displayHelp; }
290                 }
291                 
292                 public bool NoLogo {
293                         get { return noLogo; }
294                 }
295                 
296                 public bool DisplayVersion {
297                         get { return displayVersion; }
298                 }
299                 
300                 public string ProjectFile {
301                         get { return projectFile; }
302                 }
303                 
304                 public string[] Targets {
305                         get { return targets; }
306                 }
307                 
308                 public BuildPropertyGroup Properties {
309                         get { return properties; }
310                 }
311                 
312                 public IList Loggers {
313                         get { return loggers; }
314                 }
315                 
316                 public LoggerVerbosity LoggerVerbosity {
317                         get { return loggerVerbosity; }
318                 }
319                 
320                 public string ConsoleLoggerParameters {
321                         get { return consoleLoggerParameters; }
322                 }
323                 
324                 public bool NoConsoleLogger {
325                         get { return noConsoleLogger; }
326                 }
327                 
328                 public bool Validate {
329                         get { return validate; }
330                 }
331                 
332                 public string ValidationSchema {
333                         get { return validationSchema; }
334                 }
335                 
336         }
337 }
338
339 #endif