Merge pull request #2798 from BrzVlad/fix-sgen-timestamp
[mono.git] / mcs / class / Microsoft.Build.Utilities / Microsoft.Build.Utilities / CommandLineBuilder.cs
1 //
2 // CommandLineBuilder.cs: Builds command line options string
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
29 using System;
30 using System.Collections;
31 using System.Text;
32 using System.Text.RegularExpressions;
33 using Microsoft.Build.Framework;
34
35 namespace Microsoft.Build.Utilities
36 {
37         public class CommandLineBuilder
38         {
39                 StringBuilder commandLine;
40                 static char [] chars;
41         
42                 static CommandLineBuilder ()
43                 {
44                         chars = new char [] {' ', '\t', '\n', '\u000b', '\u000c', '\'', '\"', ';'};
45                 }
46                 
47                 public CommandLineBuilder ()
48                 {
49                         commandLine = new StringBuilder ();
50                 }
51                 
52                 public void AppendFileNameIfNotNull (string fileName)
53                 {
54                         if (fileName == null)
55                                 return;
56                         
57                         VerifyThrowNoEmbeddedDoubleQuotes (null, fileName);
58                         AppendSpaceIfNotEmpty ();
59                         AppendFileNameWithQuoting (fileName);
60                 }
61                 
62                 public void AppendFileNameIfNotNull (ITaskItem fileItem)
63                 {
64                         if (fileItem == null)
65                                 return;
66                         
67                         string filename = fileItem.ToString ();
68                         VerifyThrowNoEmbeddedDoubleQuotes (null, filename);
69                         AppendSpaceIfNotEmpty ();
70                         AppendFileNameWithQuoting (filename);
71                 }
72                 
73                 public void AppendFileNamesIfNotNull (string[] fileNames,
74                                                       string delimiter)
75                 {
76                         if (delimiter == null)
77                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
78                 
79                         if (fileNames == null)
80                                 return;
81                         
82                         bool appendDelimiter = false;
83                         AppendSpaceIfNotEmpty ();
84                         for (int i = 0; i < fileNames.Length; i++) {
85                                 string filename = fileNames [i];
86                                 if (filename == null)
87                                         continue;
88                                 VerifyThrowNoEmbeddedDoubleQuotes (null, filename);
89                                 if (appendDelimiter) {
90                                         commandLine.Append (delimiter);
91                                         AppendFileNameWithQuoting (filename);
92                                 } else {
93                                         AppendFileNameWithQuoting (filename);
94                                         appendDelimiter = true;
95                                 }
96                         }
97                 }
98                 
99                 public void AppendFileNamesIfNotNull (ITaskItem[] fileItems,
100                                                       string delimiter)
101                 {
102                         if (delimiter == null)
103                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
104                 
105                         if (fileItems == null)
106                                 return;
107                         
108                         bool appendDelimiter = false;
109                         AppendSpaceIfNotEmpty ();
110                         for (int i = 0; i < fileItems.Length; i++) {
111                                 string filename = fileItems [i].ToString ();
112                                 if (fileItems [i] == null)
113                                         continue;
114
115                                 VerifyThrowNoEmbeddedDoubleQuotes (null, filename);
116                                 if (appendDelimiter) {
117                                         commandLine.Append (delimiter);
118                                         AppendFileNameWithQuoting (filename);
119                                 } else {
120                                         AppendFileNameWithQuoting (filename);
121                                         appendDelimiter = true;
122                                 }
123                         }
124                 }
125                 
126                 protected void AppendFileNameWithQuoting (string fileName)
127                 {
128                         if (fileName == null)
129                                 return;
130
131                         if (IsQuotingRequired (fileName))
132                                 commandLine.AppendFormat ("\"{0}\"",fileName);
133                         else
134                                 commandLine.Append (fileName);
135                 }
136                 
137                 protected void AppendSpaceIfNotEmpty ()
138                 {
139                         if (commandLine.Length != 0)
140                                 commandLine.Append (' ');
141                 }
142                 
143                 public void AppendSwitch (string switchName)
144                 {
145                         if (switchName == null)
146                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
147
148                         AppendSpaceIfNotEmpty ();
149                         commandLine.Append (switchName);
150                 }
151                 
152                 public void AppendSwitchIfNotNull (string switchName,
153                                                    string parameter)
154                 {
155                         if (switchName == null)
156                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
157                 
158                         if (parameter == null)
159                                 return;
160
161                         VerifyThrowNoEmbeddedDoubleQuotes (switchName, parameter);
162                         AppendSpaceIfNotEmpty ();
163                         commandLine.Append (switchName);
164                         AppendTextWithQuoting (parameter);
165                 }
166                 
167                 public void AppendSwitchIfNotNull (string switchName,
168                                                    ITaskItem parameter)
169                 {
170                         if (switchName == null)
171                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
172                 
173                         if (parameter == null)
174                                 return;
175                         
176                         string value = parameter.ToString ();
177                         VerifyThrowNoEmbeddedDoubleQuotes (switchName, value);
178                         AppendSpaceIfNotEmpty ();
179                         commandLine.Append (switchName);
180                         AppendTextWithQuoting (value);
181                 }
182                 
183                 public void AppendSwitchIfNotNull (string switchName,
184                                                    string[] parameters,
185                                                    string delimiter)
186                 {
187                         if (switchName == null)
188                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
189                 
190                         if (delimiter == null)
191                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
192
193                         if (parameters == null)
194                                 return;
195                         
196                         AppendSpaceIfNotEmpty ();
197                         commandLine.AppendFormat ("{0}",switchName);
198                         bool appendDelimiter = false;
199                         for (int i = 0; i < parameters.Length; i++) {
200                                 string value = parameters [i];
201                                 if (value == null)
202                                         continue;
203
204                                 VerifyThrowNoEmbeddedDoubleQuotes (switchName, value);
205                                 if (appendDelimiter) {
206                                         commandLine.Append (delimiter);
207                                         AppendTextWithQuoting (value);
208                                 } else {
209                                         AppendTextWithQuoting (value);
210                                         appendDelimiter = true;
211                                 }
212                         }
213                 }
214                 
215                 public void AppendSwitchIfNotNull (string switchName,
216                                                    ITaskItem[] parameters,
217                                                    string delimiter)
218                 {
219                         if (switchName == null)
220                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
221                 
222                         if (delimiter == null)
223                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
224
225                         if (parameters == null)
226                                 return;
227                         
228                         AppendSpaceIfNotEmpty ();
229                         commandLine.AppendFormat ("{0}",switchName);
230                         bool appendDelimiter = false;
231                         for (int i = 0; i < parameters.Length; i++) {
232                                 string value = parameters [i].ToString ();
233                                 if (value == null)
234                                         continue;
235
236                                 VerifyThrowNoEmbeddedDoubleQuotes (switchName, value);
237                                 if (appendDelimiter) {
238                                         commandLine.Append (delimiter);
239                                         AppendTextWithQuoting (value);
240                                 } else {
241                                         AppendTextWithQuoting (value);
242                                         appendDelimiter = true;
243                                 }
244                         }
245                 }
246                 
247                 public void AppendSwitchUnquotedIfNotNull (string switchName,
248                                                            string parameter)
249                 {
250                         if (switchName == null)
251                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
252                 
253                         if (parameter == null)
254                                 return;
255                         
256                         AppendSpaceIfNotEmpty ();
257                         commandLine.AppendFormat ("{0}{1}", switchName, parameter);
258                 }
259
260                 public void AppendSwitchUnquotedIfNotNull (string switchName,
261                                                            ITaskItem parameter)
262                 {
263                         if (switchName == null)
264                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
265                 
266                         if (parameter == null)
267                                 return;
268                         
269                         AppendSpaceIfNotEmpty ();
270                         commandLine.AppendFormat ("{0}{1}", switchName, parameter.ItemSpec);
271                 }
272
273                 public void AppendSwitchUnquotedIfNotNull (string switchName,
274                                                            string[] parameters,
275                                                            string delimiter)
276                 {
277                         if (switchName == null)
278                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
279                 
280                         if (delimiter == null)
281                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
282
283                         if (parameters == null)
284                                 return;
285                         
286                         AppendSpaceIfNotEmpty ();
287                         commandLine.AppendFormat ("{0}",switchName);
288                         bool appendDelimiter = false;
289                         for (int i = 0; i < parameters.Length; i++) {
290                                 if (parameters [i] == null)
291                                         continue; 
292                                 if (appendDelimiter) {
293                                         commandLine.Append (delimiter);
294                                         commandLine.Append (parameters [i]);
295                                 } else {
296                                         commandLine.Append (parameters [i]);
297                                         appendDelimiter = true;
298                                 }
299                         }
300                 }
301
302                 public void AppendSwitchUnquotedIfNotNull (string switchName,
303                                                            ITaskItem[] parameters,
304                                                            string delimiter)
305                 {
306                         if (switchName == null)
307                                 throw new ArgumentNullException (null, "Parameter \"switchName\" cannot be null.");
308                 
309                         if (delimiter == null)
310                                 throw new ArgumentNullException (null, "Parameter \"delimiter\" cannot be null.");
311
312                         if (parameters == null)
313                                 return;
314                         
315                         AppendSpaceIfNotEmpty ();
316                         commandLine.AppendFormat ("{0}",switchName);
317                         bool appendDelimiter = false;
318                         for (int i = 0; i < parameters.Length; i++) {
319                                 if (parameters [i] == null)
320                                         continue;
321                                 if (appendDelimiter) {
322                                         commandLine.Append (delimiter);
323                                         commandLine.Append (parameters [i].ToString ());
324                                 } else {
325                                         commandLine.Append (parameters [i].ToString ());
326                                         appendDelimiter = true;
327                                 }
328                         }
329                 }
330
331                 public
332                 void AppendTextUnquoted (string textToAppend)
333                 {
334                         commandLine.Append (textToAppend);
335                 }
336                 
337                 protected void AppendTextWithQuoting (string textToAppend)
338                 {
339                         if (textToAppend == null)
340                                 return;
341
342                         if (IsQuotingRequired (textToAppend))
343                                 commandLine.AppendFormat ("\"{0}\"",textToAppend);
344                         else
345                                 commandLine.Append (textToAppend);
346                 }
347                 
348                 protected virtual bool IsQuotingRequired (string parameter)
349                 {
350                         return parameter != null && parameter.IndexOfAny (chars) >= 0;
351                 }
352                 
353                 protected virtual void VerifyThrowNoEmbeddedDoubleQuotes (string switchName,
354                                                                          string parameter)
355                 {
356                         if (parameter != null && parameter.IndexOf ('"') >= 0)
357                                 throw new ArgumentException (
358                                         String.Format ("Illegal quote passed to the command line switch named \"{0}\". The value was [{1}].",
359                                                 switchName, parameter));
360                 }
361                 
362                 public override string ToString ()
363                 {
364                         return commandLine.ToString ();
365                 }
366                 
367                 protected StringBuilder CommandLine {
368                         get {
369                                 return commandLine;
370                         }
371                 }
372         }
373 }
374