public ArgInfo(FieldInfo fi, GetArgs container, object defaultvalue) { this.defaultvalue = defaultvalue; this.fi = fi; this.container = container; object[] att = fi.GetCustomAttributes(typeof(ArgItemAttribute), false); if (att.Length == 0) { options = new ArgItemAttribute(); } else { options = att[0] as ArgItemAttribute; } }
/// <summary> /// Creates an instance of GetArgs /// </summary> protected GetArgs() { const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance; Type argclass = GetType(); if (re == null) { ArgOptionsAttribute aoa = argclass.GetCustomAttributes(typeof(ArgOptionsAttribute), true)[0] as ArgOptionsAttribute; casesensitive = aoa.CaseSensitive; allowshortcut = aoa.AllowShortcut; seperator = aoa.Seperator; prefix = aoa.Prefix; msgbox = aoa.MessageBox; shortlen = aoa.ShortcutLength; pauserr = aoa.PauseOnError; ignoreunknown = aoa.IgnoreUnknownArguments; re = new Regex(string.Format(@" (({0} # switch (?<name>[_A-Za-z][_\w]*) # name (any legal C# name) ({1} # sep + optional space (((""(?<value>((\\"")|[^""])*)"")| # match a double quoted value (escape "" with \) ('(?<value>((\\')|[^'])*)'))| # match a single quoted value (escape ' with \) (\{{(?<arrayval>[^\}}]*)\}})| # list value (escaped for string.Format) (?<value>\S+)) # any single value )?)| # sep option + list (((""(?<value>((\\"")|[^""])*)"")| # match a double quoted value (escape "" with \) ('(?<value>((\\')|[^'])*)'))| # match a single quoted value (escape ' with \) (\{{(?<arrayval>[^\}}]*)\}})| # list value (escaped for string.Format) (?<value>\S+)))* # any single value" , Regex.Escape(prefix), seperator.Trim() == string.Empty ? @"\s+" : @"\s*" + Regex.Escape(seperator) + @"\s*" ), RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace); arrre = new Regex(@"\s*(?<value>((\\,)|[^,])+)(\s*,\s*(?<value>((\\,)|[^,])+))*\s*", // escape , with \ RegexOptions.Compiled | RegexOptions.ExplicitCapture); } Dictionary <string, ArgInfo> argz = new Dictionary <string, ArgInfo>(); string allargs = Environment.CommandLine; allargs = allargs.Replace(string.Format(@"""{0}""", Application.ExecutablePath), "").Trim(); if (prefix == string.Empty) { throw new ArgumentException("prefix cannot be empty string"); } if (defvals == null) { defvals = this; string schemafilename = Assembly.GetEntryAssembly().Location + ".args.xsd"; string deffilename = Assembly.GetEntryAssembly().Location + ".args"; if (!File.Exists(schemafilename)) { using (TextWriter w = File.CreateText(schemafilename)) { GetSchema(w); } } if (File.Exists(deffilename)) { using (TextReader deffile = File.OpenText(deffilename)) { defvals = new XmlSerializer(GetType()).Deserialize(deffile) as GetArgs; } } else { using (TextWriter w = File.CreateText(deffilename)) { StringWriter sw = new StringWriter(); new XmlSerializer(GetType()).Serialize(sw, this); string all = sw.ToString().Replace(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", string.Empty).Replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", string.Empty); w.WriteLine(all); } } } else { return; //this } foreach (FieldInfo fi in argclass.GetFields(flags)) { object defval = fi.GetValue(defvals); string n = fi.Name; if (!casesensitive) { n = n.ToLower(); } fi.SetValue(this, defval); ArgInfo ai = new ArgInfo(fi, this, defval); if (ai.Options is DefaultArgAttribute) { argz.Add(MAGIC, ai); } //be very careful with the next line! if (!(ai.Options is DefaultArgAttribute) || ((DefaultArgAttribute)ai.Options).AllowName) { argz.Add(n, ai); if (allowshortcut) { string sn = ai.Options.Shortname; if (sn == null) { int nlen = n.Length - 1; if (nlen > 0 && shortlen < n.Length) { sn = n.Substring(0, nlen < shortlen ? nlen : shortlen); if (!argz.ContainsKey(sn)) { argz.Add(sn, ai); ai.Options.Shortname = sn; } } } else { if (!argz.ContainsKey(sn)) { argz.Add(sn, ai); } } } } } defvals = null; if (allargs.StartsWith(prefix + "?") || allargs.StartsWith(prefix + "help")) { PrintHelp(argz); Environment.Exit(0); } Group g = null; bool haserror = false; foreach (Match m in re.Matches(allargs)) { string argname = null; try { if (m.Value == string.Empty) { continue; } object val = null; if ((g = m.Groups["name"]).Success) { argname = g.Value; if (!casesensitive) { argname = argname.ToLower(); } } else { argname = MAGIC; } ArgInfo arginfo = argz[argname]; if (arginfo == null) { if (ignoreunknown) { Console.Error.WriteLine("Warning: Ignoring argument unknown '{0}'", argname); } else { Console.Error.WriteLine("Error: Argument '{0}' not known", argname); haserror = true; } continue; } Type t = arginfo.Type; if (t == null) { continue; } if (t.IsArray && argname != MAGIC) { if ((g = m.Groups["arrayval"]).Success) { Type elet = t.GetElementType(); TypeConverter tc = TypeDescriptor.GetConverter(elet); Match arrm = arrre.Match(g.Value); if (arrm.Success) { Group gg = arrm.Groups["value"]; Array arr = Array.CreateInstance(elet, gg.Captures.Count); for (int i = 0; i < arr.Length; i++) { arr.SetValue(tc.ConvertFromString(gg.Captures[i].Value.Trim()), i); } val = arr; } } } else { if ((g = m.Groups["value"]).Success) { string v = g.Value; if (t == typeof(bool) && (v == "on" || v == "off")) { val = v == "on"; } else { if (t.IsArray) { ArrayList vals = new ArrayList(); if (arginfo.Value != null) { vals.AddRange(arginfo.Value as ICollection); } TypeConverter tc = TypeDescriptor.GetConverter(t.GetElementType()); vals.Add(tc.ConvertFromString(v)); val = vals.ToArray(typeof(string)) as string[]; } else { TypeConverter tc = TypeDescriptor.GetConverter(t); val = tc.ConvertFromString(v); } } } else { val = t == typeof(bool); } } arginfo.Value = val; } catch (Exception ex) { Console.Error.WriteLine("Error: Argument '{0}' could not be read ({1})", argname, ex.Message, ex.GetBaseException().GetType().Name); haserror = true; } } if (haserror) { PrintHelp(argz); if (pauserr && !msgbox) { Console.WriteLine("Press any key to exit"); Console.Read(); } Environment.Exit(1); } }