Beispiel #1
0
        // Returns the parsed command line. If ErrorDescription is non-null, then the parse failed.
        internal static CommandLineOptions ParseCommandLine(string[] args)
        {
            var result = new CommandLineOptions();

            result.ParseCommandLineStrings(args);

            // Convert the language strings to language values.
            var languageTokenizer = new CommandlineTokenizer <Language>(Language.Ambiguous)
                                    .AddKeyword(Language.CSharp)
                                    .AddKeyword(Language.Cx, "cppcx")
                                    .AddKeyword(Language.Cx)
                                    .AddKeyword(Language.Cppwinrt)
                                    .AddKeyword(Language.Cppwinrt, "winrtcpp")
                                    .AddKeyword(Language.LottieYaml)
                                    .AddKeyword(Language.WinCompDgml, "dgml")
                                    .AddKeyword(Language.Stats);

            var languages = new List <Language>();

            // Parse the language string.
            foreach (var languageString in result._languageStrings)
            {
                languageTokenizer.TryMatchKeyword(languageString, out var language);
                languages.Add(language);
                switch (language)
                {
                case Language.Unknown:
                    result.ErrorDescription = $"Unrecognized language: {languageString}";
                    break;

                case Language.Ambiguous:
                    result.ErrorDescription = $"Ambiguous language: {languageString}";
                    break;
                }
            }

            result.Languages = languages.Distinct().ToArray();

            // Sort any additional interfaces and remove duplicates.
            var additionalInterfaces = result._additionalInterfaces.OrderBy(name => name).Distinct().ToArray();

            result._additionalInterfaces.Clear();
            result._additionalInterfaces.AddRange(additionalInterfaces);

            return(result);
        }
Beispiel #2
0
        void ParseCommandLineStrings(string[] args)
        {
            // Define the keywords accepted on the command line.
            var tokenizer = new CommandlineTokenizer <Keyword>(ambiguousValue: Keyword.Ambiguous)
                            .AddPrefixedKeyword(Keyword.AdditionalInterface)
                            .AddPrefixedKeyword(Keyword.DisableCodeGenOptimizer)
                            .AddPrefixedKeyword(Keyword.DisableTranslationOptimizer)
                            .AddPrefixedKeyword(Keyword.GenerateColorBindings)
                            .AddPrefixedKeyword(Keyword.GenerateDependencyObject)
                            .AddPrefixedKeyword(Keyword.Help, "?")
                            .AddPrefixedKeyword(Keyword.Help)
                            .AddPrefixedKeyword(Keyword.InputFile)
                            .AddPrefixedKeyword(Keyword.Interface)
                            .AddPrefixedKeyword(Keyword.Language)
                            .AddPrefixedKeyword(Keyword.MinimumUapVersion)
                            .AddPrefixedKeyword(Keyword.Namespace)
                            .AddPrefixedKeyword(Keyword.OutputFolder)
                            .AddPrefixedKeyword(Keyword.Public)
                            .AddPrefixedKeyword(Keyword.RootNamespace)
                            .AddPrefixedKeyword(Keyword.Strict)
                            .AddPrefixedKeyword(Keyword.TargetUapVersion)
                            .AddPrefixedKeyword(Keyword.TestMode)
                            .AddPrefixedKeyword(Keyword.WinUIVersion);

            // The last keyword recognized. This defines what the following parameter value is for,
            // or None if not expecting a parameter value.
            var previousKeyword = Keyword.None;

            foreach (var(keyword, arg) in tokenizer.Tokenize(args))
            {
                var prev = previousKeyword;
                previousKeyword = Keyword.None;
                switch (prev)
                {
                case Keyword.None:
                    // Expecting a keyword.
                    switch (keyword)
                    {
                    case Keyword.Ambiguous:
                        ErrorDescription = $"Ambiguous: \"{arg}\".";
                        return;

                    case Keyword.None:
                        ErrorDescription = $"Unexpected: \"{arg}\".";
                        return;

                    case Keyword.GenerateColorBindings:
                        GenerateColorBindings = true;
                        break;

                    case Keyword.GenerateDependencyObject:
                        GenerateDependencyObject = true;
                        break;

                    case Keyword.Help:
                        HelpRequested = true;
                        return;

                    case Keyword.Strict:
                        StrictMode = true;
                        break;

                    case Keyword.TestMode:
                        TestMode = true;
                        break;

                    case Keyword.DisableCodeGenOptimizer:
                        DisableCodeGenOptimizer = true;
                        break;

                    case Keyword.DisableTranslationOptimizer:
                        DisableTranslationOptimizer = true;
                        break;

                    case Keyword.Public:
                        Public = true;
                        break;

                    // The following keywords require a parameter as the next token.
                    case Keyword.AdditionalInterface:
                    case Keyword.InputFile:
                    case Keyword.Interface:
                    case Keyword.Language:
                    case Keyword.Namespace:
                    case Keyword.OutputFolder:
                    case Keyword.MinimumUapVersion:
                    case Keyword.RootNamespace:
                    case Keyword.TargetUapVersion:
                    case Keyword.WinUIVersion:
                        previousKeyword = keyword;
                        break;

                    default:
                        // Should never get here.
                        throw new InvalidOperationException();
                    }

                    break;

                case Keyword.AdditionalInterface:
                    _additionalInterfaces.Add(arg);
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.InputFile:
                    if (InputFile != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Input");
                        return;
                    }

                    InputFile       = arg;
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.Language:
                    _languageStrings.Add(arg);
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.Namespace:
                    if (Namespace != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Namespace");
                        return;
                    }

                    Namespace       = arg;
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.OutputFolder:
                    if (OutputFolder != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Output folder");
                        return;
                    }

                    OutputFolder    = arg;
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.MinimumUapVersion:
                    if (MinimumUapVersion != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Minimum UAP version");
                        return;
                    }

                    {
                        if (!uint.TryParse(arg, out var version))
                        {
                            ErrorDescription = ArgumentMustBeAPositiveInteger("Minimum UAP version");
                            return;
                        }

                        MinimumUapVersion = version;
                    }

                    previousKeyword = Keyword.None;
                    break;

                case Keyword.RootNamespace:
                    if (RootNamespace != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Output folder");
                        return;
                    }

                    RootNamespace   = arg;
                    previousKeyword = Keyword.None;
                    break;

                case Keyword.TargetUapVersion:
                    if (TargetUapVersion != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("Target UAP version");
                        return;
                    }

                    {
                        if (!uint.TryParse(arg, out var version))
                        {
                            ErrorDescription = ArgumentMustBeAPositiveInteger("Target UAP version");
                            return;
                        }

                        TargetUapVersion = version;
                    }

                    previousKeyword = Keyword.None;
                    break;

                case Keyword.WinUIVersion:
                    if (_winUIVersion != null)
                    {
                        ErrorDescription = ArgumentSpecifiedMoreThanOnce("WinUI version");
                        return;
                    }

                    {
                        if (!Version.TryParse(arg, out var version))
                        {
                            ErrorDescription = ArgumentMustBeAMajorAndMinorVerion("WinUI version");
                            return;
                        }

                        _winUIVersion = version;
                    }

                    previousKeyword = Keyword.None;
                    break;

                default:
                    // Should never get here.
                    throw new InvalidOperationException();
                }
            }

            // All tokens consumed. Ensure we are not waiting for the final parameter value.
            if (previousKeyword != Keyword.None)
            {
                ErrorDescription = "Missing value.";
            }
        }