Exemplo n.º 1
0
        private static void ExpandOptionBundle(IList <ArgumentToken> receiver, int index)
        {
            var options = receiver[index].Name;

            receiver.RemoveAt(index);

            foreach (var c in options)
            {
                var name          = char.ToString(c);
                var expandedToken = new ArgumentToken(@"-", name, null);
                receiver.Insert(index, expandedToken);
                index++;
            }
        }
Exemplo n.º 2
0
 private static bool IsOptionBundle(ArgumentToken token)
 {
     return(token.IsOption &&
            token.Modifier == @"-" &&
            token.Name.Length > 1);
 }
Exemplo n.º 3
0
        public static IReadOnlyList <ArgumentToken> Lex(IEnumerable <string> args, Func <string, IEnumerable <string> > responseFileReader = null)
        {
            var result = new List <ArgumentToken>();

            // We'll split the arguments into tokens.
            //
            // A token combines the modifier (/, -, --), the option name, and the option
            // value.
            //
            // Please note that this code doesn't combine arguments. It only provides
            // some pre-processing over the arguments to split out the modifier,
            // option, and value:
            //
            // { "--out", "out.exe" } ==> { new ArgumentToken("--", "out", null),
            //                              new ArgumentToken(null, null, "out.exe") }
            //
            // {"--out:out.exe" }     ==> { new ArgumentToken("--", "out", "out.exe") }
            //
            // The reason it doesn't combine arguments is because it depends on the actual
            // definition. For example, if --out is a flag (meaning it's of type bool) then
            // out.exe in the first example wouldn't be considered its value.
            //
            // The code also handles the special -- token which indicates that the following
            // arguments shouldn't be considered options.
            //
            // Finally, this code will also expand any reponse file entries, assuming the caller
            // gave us a non-null reader.

            var hasSeenDashDash = false;

            foreach (var arg in ExpandResponseFiles(args, responseFileReader))
            {
                // If we've seen a -- already, then we'll treat one as a plain name, that is
                // without a modifier or value.

                if (!hasSeenDashDash && arg == @"--")
                {
                    hasSeenDashDash = true;
                    continue;
                }

                string modifier;
                string name;
                string value;

                if (hasSeenDashDash)
                {
                    modifier = null;
                    name     = arg;
                    value    = null;
                }
                else
                {
                    // If we haven't seen the -- separator, we're looking for options.
                    // Options have leading modifiers, i.e. /, -, or --.
                    //
                    // Options can also have values, such as:
                    //
                    //      -f:false
                    //      --name=hello


                    if (!TryExtractOption(arg, out modifier, out string nameAndValue))
                    {
                        name  = arg;
                        value = null;
                    }
                    else if (!TrySplitNameValue(nameAndValue, out name, out value))
                    {
                        name  = nameAndValue;
                        value = null;
                    }
                }

                var token = new ArgumentToken(modifier, name, value);
                result.Add(token);
            }

            // Single letter options can be combined, for example the following two
            // forms are considered equivalent:
            //
            //    (1)  -xdf
            //    (2)  -x -d -f
            //
            // In order to free later phases from handling this case, we simply expand
            // single letter options to the second form.

            for (var i = result.Count - 1; i >= 0; i--)
            {
                if (IsOptionBundle(result[i]))
                {
                    ExpandOptionBundle(result, i);
                }
            }

            return(result.ToArray());
        }