4 // Author: Rafael Teixeira (rafaelteixeirabr@hotmail.com) (original)
5 // Author: Dean Scarff (D_Scarff@AIMINGFORSPAMFREEmsn.com) (modifications)
7 // (C) 2002 Rafael Teixeira
8 // Modifications (C) 2002 Dean Scarff, distributed under the Gnu General Public License Version 2 or later
12 using System.Collections;
14 using System.Reflection;
16 namespace Mono.GetOptions
20 public enum OptionsParsingMode
30 public class OptionList
33 private Options optionBundle = null;
34 private OptionsParsingMode parsingMode;
35 private bool endOptionProcessingWithDoubleDash;
37 private string appExeName;
38 private string appVersion;
40 private string appTitle = "Add a [assembly: AssemblyTitle(\"Here goes the application name\")] to your assembly";
41 private string appCopyright = "Add a [assembly: AssemblyCopyright(\"(c)200n Here goes the copyright holder name\")] to your assembly";
42 private string appDescription = "Add a [assembly: AssemblyDescription(\"Here goes the short description\")] to your assembly";
43 private string appAboutDetails = "Add a [assembly: Mono.About(\"Here goes the short about details\")] to your assembly";
44 private string appUsageComplement = "Add a [assembly: Mono.UsageComplement(\"Here goes the usage clause complement\")] to your assembly";
45 private string[] appAuthors;
47 private ArrayList list = new ArrayList();
48 private ArrayList arguments = new ArrayList();
49 private ArrayList argumentsTail = new ArrayList();
55 return "Usage: " + appExeName + " [options] " + appUsageComplement;
59 public string AboutDetails
63 return appAboutDetails;
67 #region Assembly Attributes
71 private object[] GetAssemblyAttributes(Type type)
73 return entry.GetCustomAttributes(type, false);
76 private string[] GetAssemblyAttributeStrings(Type type)
78 object[] result = GetAssemblyAttributes(type);
80 if ((result == null) || (result.Length == 0))
84 string[] var = new string[result.Length];
86 foreach(object o in result)
87 var[i++] = o.ToString();
92 private void GetAssemblyAttributeValue(Type type, string propertyName, ref string var)
94 object[] result = GetAssemblyAttributes(type);
96 if ((result != null) && (result.Length > 0))
97 var = (string)type.InvokeMember(propertyName, BindingFlags.Public | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance, null, result[0], new object [] {}); ;
100 private void GetAssemblyAttributeValue(Type type, ref string var)
102 object[] result = GetAssemblyAttributes(type);
104 if ((result != null) && (result.Length > 0))
105 var = result[0].ToString();
112 private void Initialize(Options optionBundle)
114 if (optionBundle == null)
115 throw new ArgumentNullException("optionBundle");
117 entry = Assembly.GetEntryAssembly();
118 appExeName = entry.GetName().Name;
119 appVersion = entry.GetName().Version.ToString();
121 this.optionBundle = optionBundle;
122 this.parsingMode = optionBundle.ParsingMode ;
123 this.endOptionProcessingWithDoubleDash = optionBundle.EndOptionProcessingWithDoubleDash;
125 GetAssemblyAttributeValue(typeof(AssemblyTitleAttribute), "Title", ref appTitle);
126 GetAssemblyAttributeValue(typeof(AssemblyCopyrightAttribute), "Copyright", ref appCopyright);
127 GetAssemblyAttributeValue(typeof(AssemblyDescriptionAttribute), "Description", ref appDescription);
128 GetAssemblyAttributeValue(typeof(Mono.AboutAttribute), ref appAboutDetails);
129 GetAssemblyAttributeValue(typeof(Mono.UsageComplementAttribute), ref appUsageComplement);
130 appAuthors = GetAssemblyAttributeStrings(typeof(AuthorAttribute));
131 if (appAuthors.Length == 0)
133 appAuthors = new String[1];
134 appAuthors[0] = "Add one or more [assembly: Mono.GetOptions.Author(\"Here goes the author name\")] to your assembly";
137 foreach(MemberInfo mi in optionBundle.GetType().GetMembers())
139 object[] attribs = mi.GetCustomAttributes(typeof(OptionAttribute), true);
140 if (attribs != null && attribs.Length > 0)
141 list.Add(new OptionDetails(mi, (OptionAttribute)attribs[0], optionBundle));
145 public OptionList(Options optionBundle)
147 Initialize(optionBundle);
152 #region Prebuilt Options
154 private void ShowTitleLines()
156 Console.WriteLine(appTitle + " " + appVersion + " - " + appCopyright);
157 Console.WriteLine(appDescription);
161 private void ShowAbout()
164 Console.WriteLine(appAboutDetails);
166 Console.WriteLine("Authors:");
167 foreach(string s in appAuthors)
168 Console.WriteLine ("\t" + s);
171 private void ShowHelp()
174 Console.WriteLine(Usage);
175 Console.WriteLine("Options:");
176 foreach (OptionDetails option in list)
177 Console.WriteLine(option);
180 private void ShowUsage()
182 Console.WriteLine(Usage);
183 Console.Write("Short Options: ");
184 foreach (OptionDetails option in list)
185 Console.Write((option.ShortForm != ' ') ? option.ShortForm.ToString() : "");
190 private void ShowUsage(string errorMessage)
192 Console.WriteLine("ERROR: " + errorMessage.TrimEnd());
196 internal WhatToDoNext DoUsage()
199 return WhatToDoNext.AbandonProgram;
202 internal WhatToDoNext DoAbout()
205 return WhatToDoNext.GoAhead;
208 internal WhatToDoNext DoHelp()
211 return WhatToDoNext.AbandonProgram;
216 #region Arguments Processing
218 public string[] NormalizeArgs(string[] args)
220 bool ParsingOptions = true;
221 ArrayList result = new ArrayList();
223 foreach(string arg in args)
227 if (endOptionProcessingWithDoubleDash && (arg == "--"))
229 ParsingOptions = false;
233 if ((parsingMode & OptionsParsingMode.Windows) > 0)
235 if ((arg.Length == 2) && (arg[0] == '/')) // Windows options only come in this fashion
237 result.Add("-" + arg[1]); // translate to Linux style
242 if ((parsingMode & OptionsParsingMode.Linux) > 0)
244 if ((arg[0] == '-') && (arg[1] != '-'))
246 foreach(char c in arg.Substring(1)) // many single-letter options
247 result.Add("-" + c); // expand into individualized options
251 if (arg.StartsWith("--"))
253 result.AddRange(arg.Split('=')); // put in the same form of one-letter options with a parameter
260 argumentsTail.Add(arg);
264 // if nothing else matches then it get here
268 return (string[])result.ToArray(typeof(string));
271 public string[] ProcessArgs(string[] args)
275 bool OptionWasProcessed;
279 args = NormalizeArgs(args);
283 int argc = args.Length;
284 for(int i = 0; i < argc; i++)
290 if (nextArg.StartsWith("-"))
296 OptionWasProcessed = false;
298 if (arg.StartsWith("-"))
300 foreach(OptionDetails option in list)
302 if (option.ProcessArgument(arg, nextArg))
304 OptionWasProcessed = true;
312 if (!OptionWasProcessed)
316 foreach(OptionDetails option in list)
317 option.TransferValues();
319 foreach(string argument in argumentsTail)
320 arguments.Add(argument);
324 ShowUsage(ex.Message);
325 System.Environment.Exit(1);
328 return (string[])arguments.ToArray(typeof(string));