~ubuntu-branches/ubuntu/jaunty/beagle/jaunty-security

« back to all changes in this revision

Viewing changes to bludgeon/CommandLineFu.cs

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Ebner
  • Date: 2008-05-04 00:31:32 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20080504003132-2tkm5o8moo5952ri
Tags: 0.3.7-2ubuntu1
 * Merge from Debian unstable. (LP: #225746) Remaining Ubuntu changes:
  - debian/control:
    + Rename ice{weasel,dove}-beagle to {mozilla,thunderbird}-beagle and
      and update the dependencies accordingly.
    + Change Maintainer to Ubuntu Mono Team.
  - debian/rules:
    + Install the mozilla-beagle and thunderbird-beagle extensions.
  - ice{dove,weasel}.dirs:
    + Renamed to {mozilla,thunderbird}-beagle.dirs.
    + Fixed paths to point to usr/lib/{firefox,thunderbird}

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// CommandLineFu.cs
3
 
//
4
 
// Copyright (C) 2005 Novell, Inc.
5
 
//
6
 
 
7
 
//
8
 
// Permission is hereby granted, free of charge, to any person obtaining a
9
 
// copy of this software and associated documentation files (the "Software"),
10
 
// to deal in the Software without restriction, including without limitation
11
 
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 
// and/or sell copies of the Software, and to permit persons to whom the
13
 
// Software is furnished to do so, subject to the following conditions:
14
 
//
15
 
// The above copyright notice and this permission notice shall be included in
16
 
// all copies or substantial portions of the Software.
17
 
//
18
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 
// DEALINGS IN THE SOFTWARE.
25
 
//
26
 
 
27
 
using System;
28
 
using System.Collections;
29
 
using System.Reflection;
30
 
using System.Text;
31
 
 
32
 
namespace CommandLineFu {
33
 
 
34
 
        [AttributeUsage (AttributeTargets.Field)]
35
 
        public class OptionAttribute : Attribute {
36
 
                public string Name;
37
 
                public string LongName;
38
 
                public string Description = "(no description)";
39
 
                public string ArgDescription = "arg";
40
 
        }
41
 
 
42
 
        internal class Processor {
43
 
 
44
 
                object target_object;
45
 
 
46
 
                public Processor (object target_object)
47
 
                {
48
 
                        this.target_object = target_object;
49
 
                }
50
 
 
51
 
                ///////////////////////////////////////////////////////////////////
52
 
 
53
 
                private class Pair {
54
 
 
55
 
                        public FieldInfo Field;
56
 
                        public OptionAttribute Option;
57
 
 
58
 
                        private object target_object;
59
 
                        private bool touched = false;
60
 
 
61
 
 
62
 
                        public Pair (object target)
63
 
                        {
64
 
                                target_object = target;
65
 
                        }
66
 
 
67
 
                        public string Name {
68
 
                                get { return Field.Name; }
69
 
                        }
70
 
 
71
 
                        public string OptionName {
72
 
                                get {
73
 
                                        if (Option.LongName != null)
74
 
                                                return "--" + Option.LongName;
75
 
                                        else
76
 
                                                return "-" + Option.Name;
77
 
                                }
78
 
                        }
79
 
 
80
 
                        public string UsageName {
81
 
                                get {
82
 
                                        StringBuilder builder = new StringBuilder ();
83
 
                                        if (Option.LongName != null) {
84
 
                                                builder.Append ("--");
85
 
                                                builder.Append (Option.LongName);
86
 
                                                
87
 
                                                if (Option.Name != null)
88
 
                                                        builder.Append (", ");
89
 
                                        }
90
 
                                        if (Option.Name != null) {
91
 
                                                builder.Append ("-");
92
 
                                                builder.Append (Option.Name);
93
 
                                        }
94
 
                                        if (Field.FieldType != typeof (System.Boolean)) {
95
 
                                                builder.Append (" [");
96
 
                                                builder.Append (Option.ArgDescription);
97
 
                                                builder.Append ("]");
98
 
                                        }
99
 
                                        return builder.ToString ();
100
 
                                }
101
 
                        }
102
 
 
103
 
                        public bool Touched {
104
 
                                get { return touched; }
105
 
                        }
106
 
 
107
 
                        public object Value {
108
 
                                get { return Field.GetValue (target_object); }
109
 
                        }
110
 
 
111
 
                        // Return true if value was actually used
112
 
                        public bool Set (string value)
113
 
                        {
114
 
                                touched = true;
115
 
 
116
 
                                // Deal with bools first, since they are easy.
117
 
                                if (Field.FieldType == typeof (System.Boolean)) {
118
 
                                        Field.SetValue (target_object, true);
119
 
                                        return false;
120
 
                                }
121
 
 
122
 
                                object parsed_value = null;
123
 
 
124
 
                                if (Field.FieldType == typeof (System.String)) {
125
 
 
126
 
                                        parsed_value = value;
127
 
 
128
 
                                }  else if (Field.FieldType == typeof (System.Int32)) {
129
 
 
130
 
                                        try {
131
 
                                                parsed_value = System.Int32.Parse (value);
132
 
                                        } catch {
133
 
                                                // parsed_value will still be null, so the
134
 
                                                // "Couldn't parse..." error will be displayed.
135
 
                                        }
136
 
 
137
 
                                } else if (Field.FieldType == typeof (System.Double)) {
138
 
 
139
 
                                        try {
140
 
                                                parsed_value = System.Double.Parse (value);
141
 
                                        } catch { }                             
142
 
                                }
143
 
                                
144
 
                                if (parsed_value != null) {
145
 
                                        Field.SetValue (target_object, parsed_value);
146
 
                                } else {
147
 
                                        Console.WriteLine ("Couldn't parse '{0}' as {1}", value, Field.FieldType);
148
 
                                }
149
 
 
150
 
                                return true;
151
 
                        }
152
 
                }
153
 
 
154
 
                ArrayList all_pairs = new ArrayList ();
155
 
                Hashtable by_name = new Hashtable ();
156
 
                Hashtable by_long_name = new Hashtable ();
157
 
                
158
 
                public void AddOption (FieldInfo field, OptionAttribute option)
159
 
                {
160
 
                        Pair pair = new Pair (target_object);
161
 
                        pair.Field = field;
162
 
                        pair.Option = option;
163
 
 
164
 
                        all_pairs.Add (pair);
165
 
 
166
 
                        if (option.Name != null)
167
 
                                by_name [option.Name] = pair;
168
 
 
169
 
                        if (option.LongName != null)
170
 
                                by_long_name [option.LongName] = pair;
171
 
                }
172
 
 
173
 
                private static bool IsOption (string arg)
174
 
                {
175
 
                        return arg.StartsWith ("-") || arg.StartsWith ("/");
176
 
                }
177
 
 
178
 
                private Pair ParseOption (string arg, out string next_arg)
179
 
                {
180
 
                        next_arg = null;
181
 
 
182
 
                        char [] separator_chars = new char [] { '=', ':' };
183
 
                        int i = arg.IndexOfAny (separator_chars);
184
 
                        if (i != -1) {
185
 
                                next_arg = arg.Substring (i+1);
186
 
                                arg = arg.Substring (0, i);
187
 
                        }
188
 
 
189
 
                        string stripped_arg = null;
190
 
                        if (arg.StartsWith ("/")) {
191
 
                                stripped_arg = arg.Substring (1);
192
 
                        } else if (arg.StartsWith ("-")) {
193
 
                                int pos = 1;
194
 
                                while (pos < arg.Length && arg [pos] == '-')
195
 
                                        ++pos;
196
 
                                stripped_arg = arg.Substring (pos);
197
 
                        }
198
 
 
199
 
                        Pair pair = null;
200
 
                        pair = by_long_name [stripped_arg] as Pair;
201
 
                        if (pair == null)
202
 
                                pair = by_name [stripped_arg] as Pair;
203
 
 
204
 
                        return pair;
205
 
                }
206
 
 
207
 
                ///////////////////////////////////////////////////////////////////
208
 
 
209
 
                public void Spew ()
210
 
                {
211
 
                        foreach (Pair pair in all_pairs) {
212
 
                                Console.WriteLine ("DEBUG  {0}: {1}={2} {3}",
213
 
                                                   pair.OptionName,
214
 
                                                   pair.Name,
215
 
                                                   pair.Value,
216
 
                                                   pair.Touched ? "" : "(default)");
217
 
                        }
218
 
                }
219
 
 
220
 
                ///////////////////////////////////////////////////////////////////
221
 
 
222
 
                public void SpewVersion ()
223
 
                {
224
 
                        Console.WriteLine (CommandLine.ProgramVersion != null ? CommandLine.ProgramVersion : "unknown");
225
 
                }
226
 
 
227
 
                public void SpewBanner ()
228
 
                {
229
 
                        if (CommandLine.ProgramName == null)
230
 
                                return;
231
 
                        Console.Write (CommandLine.ProgramName);
232
 
                        if (CommandLine.ProgramVersion != null) {
233
 
                                Console.Write (" ");
234
 
                                Console.Write (CommandLine.ProgramVersion);
235
 
                        }
236
 
                        if (CommandLine.ProgramDate != null) {
237
 
                                Console.Write (" - ");
238
 
                                Console.Write (CommandLine.ProgramDate);
239
 
                        }
240
 
                        Console.WriteLine ();
241
 
 
242
 
                        if (CommandLine.ProgramCopyright != null)
243
 
                                Console.WriteLine (CommandLine.ProgramCopyright);
244
 
                                
245
 
                }
246
 
 
247
 
                public void SpewOptionDocs ()
248
 
                {
249
 
                        int max_usage_name_len = 0;
250
 
 
251
 
                        // FIXME: This need better formatting, wrapping of
252
 
                        // description lines, etc.
253
 
                        // It should also be put in a sane order.
254
 
 
255
 
                        Console.WriteLine ("Options:");
256
 
 
257
 
                        foreach (Pair pair in all_pairs) {
258
 
                                int len = pair.UsageName.Length;
259
 
                                if (len > max_usage_name_len)
260
 
                                        max_usage_name_len = len;
261
 
                        }
262
 
                        
263
 
                        foreach (Pair pair in all_pairs) {
264
 
                                StringBuilder builder = new StringBuilder ();
265
 
                                string usage_name = pair.UsageName;
266
 
                                builder.Append ("  ");
267
 
                                builder.Append (usage_name);
268
 
                                builder.Append (' ', max_usage_name_len - usage_name.Length);
269
 
                                builder.Append ("  ");
270
 
                                builder.Append (pair.Option.Description);
271
 
                                
272
 
                                Console.WriteLine (builder.ToString ());
273
 
                        }
274
 
                }
275
 
 
276
 
                ///////////////////////////////////////////////////////////////////
277
 
                
278
 
                private string [] TheRealWork (string [] args)
279
 
                {
280
 
                        ArrayList parameters = new ArrayList ();
281
 
 
282
 
                        int i = 0;
283
 
                        bool parameters_only = false;
284
 
                        while (i < args.Length) {
285
 
                                string arg = args [i];
286
 
                                ++i;
287
 
 
288
 
                                string next_arg = null;
289
 
                                if (i < args.Length)
290
 
                                        next_arg = args [i];
291
 
                                        
292
 
                                if (parameters_only || ! IsOption (arg)) {
293
 
                                        parameters.Add (arg);
294
 
                                } else if (arg == "--") {
295
 
                                        parameters_only = true;
296
 
                                } else {
297
 
                                        string attached_next_arg = null;
298
 
                                        Pair pair = ParseOption (arg, out attached_next_arg);
299
 
 
300
 
                                        if (pair == null) {
301
 
                                                Console.WriteLine ("Ignoring unknown argument '{0}'", arg);
302
 
                                        } else if (attached_next_arg != null) {
303
 
                                                if (! pair.Set (attached_next_arg)) {
304
 
                                                        // FIXME: If we didn't use the attached arg, something must be wrong.
305
 
                                                        // Throw an exception?
306
 
                                                        Console.WriteLine ("FIXME: Didn't use attached arg '{0}' on {1}",
307
 
                                                                           attached_next_arg,
308
 
                                                                           pair.OptionName);
309
 
                                                }
310
 
                                        } else {
311
 
                                                if (pair.Set (next_arg))
312
 
                                                        ++i;
313
 
                                        }
314
 
                                }
315
 
                        }
316
 
 
317
 
                        // If we ended prematurely, treat everything that is left
318
 
                        // as a parameter.
319
 
                        while (i < args.Length)
320
 
                                parameters.Add (args [i]);
321
 
                        
322
 
                        // Convert the list of parameters to an array and return it.
323
 
                        string [] parameter_array = new string [parameters.Count];
324
 
                        for (int j = 0; j < parameters.Count; ++j)
325
 
                                parameter_array [j] = parameters [j] as string;
326
 
                        return parameter_array;
327
 
                }
328
 
 
329
 
                public string [] Process (string [] args)
330
 
                {
331
 
                        foreach (string arg in args) {
332
 
                                // FIXME: These should be displayed in the banner information.
333
 
                                if (arg == "--version") {
334
 
                                        SpewVersion ();
335
 
                                        return null;
336
 
                                } else if (arg == "--help") {
337
 
                                        SpewBanner ();
338
 
                                        SpewOptionDocs ();
339
 
                                        return null;
340
 
                                }
341
 
                        }
342
 
 
343
 
                        string [] parameters = TheRealWork (args);
344
 
 
345
 
                        if (CommandLine.Debug) {
346
 
                                Spew ();
347
 
                                for (int i = 0; i < parameters.Length; ++i)
348
 
                                        Console.WriteLine ("DEBUG  Param {0}: {1}", i, parameters [i]);
349
 
                        }
350
 
                        
351
 
                        return parameters;
352
 
                }
353
 
        }
354
 
 
355
 
        public class CommandLine {
356
 
 
357
 
                static public bool Debug = false;
358
 
 
359
 
                static public string ProgramName = null;
360
 
                static public string ProgramVersion = null;
361
 
                static public string ProgramDate = null;
362
 
                static public string ProgramCopyright = null;
363
 
                static public string ProgramHomePage = null;
364
 
 
365
 
                static private Processor BuildProcessor (Type type, object obj, BindingFlags flags)
366
 
                {
367
 
                        Processor proc = new Processor (obj);
368
 
 
369
 
                        flags |= BindingFlags.NonPublic;
370
 
                        flags |= BindingFlags.Public;
371
 
 
372
 
                        FieldInfo [] field_info_array = type.GetFields (flags);
373
 
                        foreach (FieldInfo fi in field_info_array) {
374
 
 
375
 
                                object [] attributes = fi.GetCustomAttributes (true);
376
 
                                foreach (object attr in attributes) {
377
 
                                        OptionAttribute option_attr = attr as OptionAttribute;
378
 
                                        if (option_attr != null)
379
 
                                                proc.AddOption (fi, option_attr);
380
 
                                }
381
 
                        }
382
 
 
383
 
                        return proc;
384
 
                }
385
 
 
386
 
                static public string [] Process (object obj, string [] args)
387
 
                {
388
 
                        Processor proc = BuildProcessor (obj.GetType (), obj, BindingFlags.Instance);
389
 
                        return proc.Process (args);
390
 
                }
391
 
 
392
 
                static public string [] Process (Type t, string [] args)
393
 
                {
394
 
                        Processor proc = BuildProcessor (t, null, BindingFlags.Static);
395
 
                        return proc.Process (args);
396
 
                }
397
 
 
398
 
        }
399
 
 
400
 
 
401
 
 
402
 
#if false       
403
 
        class CommandLineFu_SampleCode {
404
 
 
405
 
                [Option (Name="f",
406
 
                         LongName="foo",
407
 
                         Description="The Foo Option",
408
 
                         ArgDescription="FOOARG")]
409
 
                static private string foo = "foo_default";
410
 
 
411
 
                [Option (LongName="bar",
412
 
                         Description="The Bar Option")]
413
 
                static private int bar = 12345;
414
 
 
415
 
                [Option (LongName="baz",
416
 
                         Description="The Baz Option")]
417
 
                static private bool baz = false;
418
 
 
419
 
                [Option (Name="d",
420
 
                         Description="As you might expect, the d option")]
421
 
                static private double d = 3.14159;
422
 
 
423
 
                static void Main (string [] args)
424
 
                {
425
 
                        CommandLine.Debug = true;
426
 
                        CommandLine.Process (typeof (CommandLineFu_SampleCode), args);
427
 
                }
428
 
        }
429
 
#endif
430
 
 
431
 
}