public void AddRule(ArgRule r)
 {
     Rules.Add(r);
 }
        public string Parse(string[] args)
        {
            string lastToken     = "";
            string ruleViolation = "";

            foreach (string arg in args)
            {
                string argName = "";
                if (arg.StartsWith("-") || arg.StartsWith("/"))
                {
                    string[] parts = null;
                    argName = arg.Substring(1); // strip leading - or /

                    //
                    // process lastToken, if it has a value
                    //
                    if (lastToken.Length > 0)
                    {
                        if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
                        {
                            ruleViolation = AddArg(lastToken.Substring(1), "");  // switch with no arguments
                        }
                        else
                        {
                            ruleViolation = AddArg("", lastToken);               // switch-less argument
                        }
                        if (ruleViolation != "")
                        {
                            return(ruleViolation);
                        }
                        lastToken = "";
                    }

                    //
                    // does the switch have a value in the same arg ???
                    //
                    if (argName.Contains(":") || argName.Contains("="))
                    {
                        parts         = argName.Split(new char[] { ':', '=' }, 2);
                        ruleViolation = AddArg(parts[0], parts[1]);                  // switch with argument separated by : or =
                        if (ruleViolation != "")
                        {
                            return(ruleViolation);
                        }
                    }
                    else
                    {
                        lastToken = arg;                                             // switch - argument may be in next arg - wait for next iteration
                    }
                }
                else                                                                 // switchless argument - process lastToken
                {
                    if (lastToken.Length > 0)
                    {
                        if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
                        {
                            //
                            // Should the switch take an argument?
                            //
                            lastToken = lastToken.Substring(1); // trim - or /
                            ArgRule r = GetArgRule(lastToken);
                            if (r.fHasValue)
                            {
                                ruleViolation = AddArg(lastToken, arg);          // switch with value in next argument
                                if (ruleViolation != "")
                                {
                                    return(ruleViolation);
                                }
                                lastToken = "";
                            }
                            else
                            {
                                ruleViolation = AddArg(lastToken, "");              // switch takes no arguments, promote arg to lastToken
                                if (ruleViolation != "")
                                {
                                    return(ruleViolation);
                                }
                                lastToken = arg;
                            }
                        }
                        else
                        {
                            ruleViolation = AddArg("", lastToken);                  // switch-less argument
                            if (ruleViolation != "")
                            {
                                return(ruleViolation);
                            }
                            lastToken = "";
                        }
                    }
                    else
                    {
                        lastToken = arg;
                    }
                }
            }

            //
            // Process lastToken if one exists
            //
            if (lastToken.Length > 0)
            {
                if (lastToken.StartsWith("-") || lastToken.StartsWith("/"))
                {
                    ruleViolation = AddArg(lastToken.Substring(1), "");              // switch takes no arguments, promote arg to lastToken
                    if (ruleViolation != "")
                    {
                        return(ruleViolation);
                    }
                }
                else
                {
                    ruleViolation = AddArg("", lastToken);                  // switch-less argument
                    if (ruleViolation != "")
                    {
                        return(ruleViolation);
                    }
                }
            }

            if (ruleViolation != "")
            {
                return(ruleViolation);
            }

            //
            // Evaluate missing required switches
            //

            foreach (ArgRule r in Rules)
            {
                if (r.fMustAppear && (GetArgs(r.name).Count == 0))
                {
                    if (r.name == "")
                    {
                        return(@"Required value is missing.");
                    }
                    else
                    {
                        return(@"Required switch " + r.name + " is missing.");
                    }
                }
            }

            return("");
        }
        private string AddArg(string name, string value)
        {
            // check rules
            ArgRule r = GetArgRule(name);

            if (r == null && name == "")
            {
                return(@"Invalid argument: " + value);
            }
            if (r == null)
            {
                return(@"Invalid switch: " + name);
            }

            if (r.fInsensitive)
            {
                name = name.ToLower();
            }

            if (r.fDuplicates == false)
            {
                if (GetArgs(name).Count > 0)
                {
                    if (name == "")
                    {
                        return(@"A switch-less value can only appear once.");
                    }
                    else
                    {
                        return(@"Switch " + name + " can only appear once.");
                    }
                }
            }
            if (r.fHasValue == false)
            {
                if (value != "")
                {
                    return(@"Switch " + name + " does not take an argument.");
                }
            }
            if (r.fHasValue == true)
            {
                if (value == "")
                {
                    return(@"Switch " + name + " requires an argument.");
                }
            }
            //
            // if fall through, we add the argument
            //
            if (value == "")
            {
                value = "true";
            }
            CommandLineArgs a = new CommandLineArgs();

            a.name  = name;
            a.value = value;
            Args.Add(a);
            return("");
        }