PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/tools/xbuild/Parameters.cs

https://bitbucket.org/steenlund/mono-2.6.7-for-amiga
C# | 401 lines | 352 code | 19 blank | 30 comment | 35 complexity | 19b086fb3bf28e9c51821db3ac99c235 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, LGPL-2.1
  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. #if NET_2_0
  28. using System;
  29. using System.IO;
  30. using System.Collections;
  31. using System.Collections.Generic;
  32. using System.Linq;
  33. using System.Text;
  34. using System.Reflection;
  35. using Microsoft.Build.BuildEngine;
  36. using Microsoft.Build.Framework;
  37. using Microsoft.Build.Utilities;
  38. namespace Mono.XBuild.CommandLine {
  39. public class Parameters {
  40. string consoleLoggerParameters;
  41. bool displayHelp;
  42. bool displayVersion;
  43. IList flatArguments;
  44. IList loggers;
  45. LoggerVerbosity loggerVerbosity;
  46. bool noConsoleLogger;
  47. bool noLogo;
  48. string projectFile;
  49. BuildPropertyGroup properties;
  50. IList remainingArguments;
  51. Hashtable responseFiles;
  52. string[] targets;
  53. bool validate;
  54. string validationSchema;
  55. string toolsVersion;
  56. string responseFile;
  57. public Parameters ()
  58. {
  59. consoleLoggerParameters = "";
  60. displayHelp = false;
  61. displayVersion = true;
  62. loggers = new ArrayList ();
  63. loggerVerbosity = LoggerVerbosity.Normal;
  64. noConsoleLogger = false;
  65. noLogo = false;
  66. properties = new BuildPropertyGroup ();
  67. targets = new string [0];
  68. responseFile = Path.Combine (
  69. Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location),
  70. "xbuild.rsp");
  71. }
  72. public void ParseArguments (string[] args)
  73. {
  74. bool autoResponse = true;
  75. flatArguments = new ArrayList ();
  76. remainingArguments = new ArrayList ();
  77. responseFiles = new Hashtable ();
  78. foreach (string s in args) {
  79. if (s.StartsWith ("/noautoresponse") || s.StartsWith ("/noautorsp")) {
  80. autoResponse = false;
  81. continue;
  82. }
  83. if (s [0] != '@') {
  84. flatArguments.Add (s);
  85. continue;
  86. }
  87. string responseFilename = Path.GetFullPath (UnquoteIfNeeded (s.Substring (1)));
  88. if (responseFiles.ContainsKey (responseFilename))
  89. ReportError (1, String.Format ("We already have {0} file.", responseFilename));
  90. responseFiles [responseFilename] = responseFilename;
  91. LoadResponseFile (responseFilename);
  92. }
  93. if (autoResponse == true) {
  94. // FIXME: we do not allow nested auto response file
  95. LoadResponseFile (responseFile);
  96. }
  97. foreach (string s in flatArguments) {
  98. if (s [0] != '/' || !ParseFlatArgument (s))
  99. remainingArguments.Add (s);
  100. }
  101. if (remainingArguments.Count == 0) {
  102. string[] sln_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*.sln");
  103. string[] proj_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*proj");
  104. if (sln_files.Length == 0 && proj_files.Length == 0)
  105. ReportError (3, "Please specify the project or solution file " +
  106. "to build, as none was found in the current directory.");
  107. if (sln_files.Length == 1 && proj_files.Length > 0) {
  108. var projects_table = new Dictionary<string, string> ();
  109. foreach (string pfile in SolutionParser.GetAllProjectFileNames (sln_files [0])) {
  110. string full_path = Path.GetFullPath (pfile);
  111. projects_table [full_path] = full_path;
  112. }
  113. if (!proj_files.Any (p => !projects_table.ContainsKey (Path.GetFullPath (p))))
  114. // if all the project files in the cur dir, are referenced
  115. // from the single .sln in the cur dir, then pick the sln
  116. proj_files = new string [0];
  117. }
  118. if (sln_files.Length + proj_files.Length > 1)
  119. ReportError (5, "Please specify the project or solution file " +
  120. "to build, as more than one solution or project file was found " +
  121. "in the current directory");
  122. if (sln_files.Length == 1)
  123. projectFile = sln_files [0];
  124. else
  125. projectFile = proj_files [0];
  126. } else if (remainingArguments.Count == 1) {
  127. projectFile = (string) remainingArguments [0];
  128. } else {
  129. ReportError (4, "Too many project files specified");
  130. }
  131. }
  132. private string UnquoteIfNeeded(string arg)
  133. {
  134. if (arg.StartsWith("\""))
  135. return arg.Substring(1, arg.Length - 2);
  136. return arg;
  137. }
  138. void LoadResponseFile (string filename)
  139. {
  140. StreamReader sr = null;
  141. string line;
  142. try {
  143. sr = new StreamReader (filename);
  144. StringBuilder sb = new StringBuilder ();
  145. while ((line = sr.ReadLine ()) != null) {
  146. int t = line.Length;
  147. for (int i = 0; i < t; i++) {
  148. char c = line [i];
  149. if (c == '#')
  150. // comment, ignore rest of the line
  151. break;
  152. if (c == '"' || c == '\'') {
  153. char end = c;
  154. for (i++; i < t; i++) {
  155. c = line [i];
  156. if (c == end)
  157. break;
  158. sb.Append (c);
  159. }
  160. } else if (c == ' ') {
  161. if (sb.Length > 0) {
  162. flatArguments.Add (sb.ToString ());
  163. sb.Length = 0;
  164. }
  165. } else
  166. sb.Append (c);
  167. }
  168. if (sb.Length > 0){
  169. flatArguments.Add (sb.ToString ());
  170. sb.Length = 0;
  171. }
  172. }
  173. } catch (IOException x) {
  174. ErrorUtilities.ReportWarning (2, String.Format (
  175. "Error loading response file. (Exception: {0}). Ignoring.",
  176. x.Message));
  177. } finally {
  178. if (sr != null)
  179. sr.Close ();
  180. }
  181. }
  182. private bool ParseFlatArgument (string s)
  183. {
  184. switch (s) {
  185. case "/help":
  186. case "/h":
  187. case "/?":
  188. ErrorUtilities.ShowUsage ();
  189. break;
  190. case "/nologo":
  191. noLogo = true;
  192. break;
  193. case "/version":
  194. case "/ver":
  195. ErrorUtilities.ShowVersion (true);
  196. break;
  197. case "/noconsolelogger":
  198. case "/noconlog":
  199. noConsoleLogger = true;
  200. break;
  201. case "/validate":
  202. case "/val":
  203. validate = true;
  204. break;
  205. default:
  206. if (s.StartsWith ("/target:") || s.StartsWith ("/t:")) {
  207. ProcessTarget (s);
  208. } else if (s.StartsWith ("/property:") || s.StartsWith ("/p:")) {
  209. if (!ProcessProperty (s))
  210. return false;
  211. } else if (s.StartsWith ("/logger:") || s.StartsWith ("/l:")) {
  212. ProcessLogger (s);
  213. } else if (s.StartsWith ("/verbosity:") || s.StartsWith ("/v:")) {
  214. ProcessVerbosity (s);
  215. } else if (s.StartsWith ("/consoleloggerparameters:") || s.StartsWith ("/clp:")) {
  216. ProcessConsoleLoggerParameters (s);
  217. } else if (s.StartsWith ("/validate:") || s.StartsWith ("/val:")) {
  218. ProcessValidate (s);
  219. } else if (s.StartsWith ("/toolsversion:") || s.StartsWith ("/tv:")) {
  220. ToolsVersion = s.Split (':') [1];
  221. } else
  222. return false;
  223. break;
  224. }
  225. return true;
  226. }
  227. internal void ProcessTarget (string s)
  228. {
  229. TryProcessMultiOption (s, "Target names must be specified as /t:Target1;Target2",
  230. out targets);
  231. }
  232. internal bool ProcessProperty (string s)
  233. {
  234. string[] splitProperties;
  235. if (!TryProcessMultiOption (s, "Property name and value expected as /p:<prop name>=<prop value>",
  236. out splitProperties))
  237. return false;
  238. foreach (string st in splitProperties) {
  239. if (st.IndexOf ('=') < 0) {
  240. ReportError (5,
  241. "Invalid syntax. Property name and value expected as " +
  242. "<prop name>=[<prop value>]");
  243. return false;
  244. }
  245. string [] property = st.Split ('=');
  246. properties.SetProperty (property [0], property.Length == 2 ? property [1] : "");
  247. }
  248. return true;
  249. }
  250. bool TryProcessMultiOption (string s, string error_message, out string[] values)
  251. {
  252. values = null;
  253. int colon = s.IndexOf (':');
  254. if (colon + 1 == s.Length) {
  255. ReportError (5, error_message);
  256. return false;
  257. }
  258. values = s.Substring (colon + 1).Split (';');
  259. return true;
  260. }
  261. private void ReportError (int errorCode, string message)
  262. {
  263. throw new CommandLineException (message, errorCode);
  264. }
  265. private void ReportError (int errorCode, string message, Exception cause)
  266. {
  267. throw new CommandLineException (message, cause, errorCode);
  268. }
  269. internal void ProcessLogger (string s)
  270. {
  271. loggers.Add (new LoggerInfo (s));
  272. }
  273. internal void ProcessVerbosity (string s)
  274. {
  275. string[] temp = s.Split (':');
  276. switch (temp [1]) {
  277. case "q":
  278. case "quiet":
  279. loggerVerbosity = LoggerVerbosity.Quiet;
  280. break;
  281. case "m":
  282. case "minimal":
  283. loggerVerbosity = LoggerVerbosity.Minimal;
  284. break;
  285. case "n":
  286. case "normal":
  287. loggerVerbosity = LoggerVerbosity.Normal;
  288. break;
  289. case "d":
  290. case "detailed":
  291. loggerVerbosity = LoggerVerbosity.Detailed;
  292. break;
  293. case "diag":
  294. case "diagnostic":
  295. loggerVerbosity = LoggerVerbosity.Diagnostic;
  296. break;
  297. }
  298. }
  299. internal void ProcessConsoleLoggerParameters (string s)
  300. {
  301. consoleLoggerParameters = s;
  302. }
  303. internal void ProcessValidate (string s)
  304. {
  305. string[] temp;
  306. validate = true;
  307. temp = s.Split (':');
  308. validationSchema = temp [1];
  309. }
  310. public bool DisplayHelp {
  311. get { return displayHelp; }
  312. }
  313. public bool NoLogo {
  314. get { return noLogo; }
  315. }
  316. public bool DisplayVersion {
  317. get { return displayVersion; }
  318. }
  319. public string ProjectFile {
  320. get { return projectFile; }
  321. }
  322. public string[] Targets {
  323. get { return targets; }
  324. }
  325. public BuildPropertyGroup Properties {
  326. get { return properties; }
  327. }
  328. public IList Loggers {
  329. get { return loggers; }
  330. }
  331. public LoggerVerbosity LoggerVerbosity {
  332. get { return loggerVerbosity; }
  333. }
  334. public string ConsoleLoggerParameters {
  335. get { return consoleLoggerParameters; }
  336. }
  337. public bool NoConsoleLogger {
  338. get { return noConsoleLogger; }
  339. }
  340. public bool Validate {
  341. get { return validate; }
  342. }
  343. public string ValidationSchema {
  344. get { return validationSchema; }
  345. }
  346. public string ToolsVersion {
  347. get { return toolsVersion; }
  348. private set { toolsVersion = value; }
  349. }
  350. }
  351. }
  352. #endif